zap_native

package
v1.28.20 Latest Latest
Warning

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

Go to latest
Published: Jun 3, 2026 License: BSD-3-Clause Imports: 8 Imported by: 0

Documentation

Overview

Package zap_native implements native ZAP encoding for platformvm txs.

Architectural anchor: there is NO marshal step. The Go struct wraps the ZAP buffer directly. Constructors write to fixed offsets. Accessors read via offset arithmetic on the buffer with zero copy and zero allocation.

The buffer IS the wire format. tx.Bytes() returns it literally. Parse(b) wraps b in a typed accessor — no decode step. TxID is hash of buffer — no re-encoding.

This file implements the simplest platformvm tx (AdvanceTimeTx, one uint64 field) as the canary for the pattern. The other ~32 tx types follow the same shape: schema offsets + Wrap function + Builder + Bytes/ID accessors.

Index

Constants

View Source
const (
	OffsetAddChainValidatorTx_NetworkID     = 1
	OffsetAddChainValidatorTx_BlockchainID  = 5
	OffsetAddChainValidatorTx_OutsList      = 37
	OffsetAddChainValidatorTx_InsList       = 45
	OffsetAddChainValidatorTx_CredsList     = 53
	OffsetAddChainValidatorTx_SigIndicesArr = 61
	OffsetAddChainValidatorTx_SigArr        = 69
	OffsetAddChainValidatorTx_Memo          = 77
	OffsetAddChainValidatorTx_NodeID        = 85
	OffsetAddChainValidatorTx_StakeStart    = 105
	OffsetAddChainValidatorTx_StakeEnd      = 113
	OffsetAddChainValidatorTx_StakeWeight   = 121
	OffsetAddChainValidatorTx_Chain         = 129
	SizeAddChainValidatorTx                 = 161
)

AddChainValidatorTx — chain/subnet validator add. POST-rebrand: this is the rebranded AddSubnetValidatorTx. The legacy code has already shipped the rename in the txs package (verified: no `Subnet` in *.go names); our v3 form pins ChainValidator semantics. ChainAuth (credential proof) lives in the signed-tx wrapper, not in the unsigned encoding here.

Fixed-section layout (size 161 bytes):

TxKind                  uint8  @ 0
NetworkID               uint32 @ 1
BlockchainID            32B    @ 5
OutsList                8B     @ 37
InsList                 8B     @ 45
CredsList               8B     @ 53
SigIndicesArr           8B     @ 61
SigArr                  8B     @ 69
Memo                    8B     @ 77
NodeID                  20B    @ 85
StakeStart              uint64 @ 105
StakeEnd                uint64 @ 113
StakeWeight             uint64 @ 121
Chain                   32B    @ 129  (ids.ID — the chain this validator joins)
View Source
const (
	OffsetAddDelegatorTx_NetworkID                  = 1
	OffsetAddDelegatorTx_BlockchainID               = 5
	OffsetAddDelegatorTx_OutsList                   = 37
	OffsetAddDelegatorTx_InsList                    = 45
	OffsetAddDelegatorTx_CredsList                  = 53
	OffsetAddDelegatorTx_SigIndicesArr              = 61
	OffsetAddDelegatorTx_SigArr                     = 69
	OffsetAddDelegatorTx_Memo                       = 77
	OffsetAddDelegatorTx_NodeID                     = 85
	OffsetAddDelegatorTx_StakeStart                 = 105
	OffsetAddDelegatorTx_StakeEnd                   = 113
	OffsetAddDelegatorTx_StakeWeight                = 121
	OffsetAddDelegatorTx_StakeOutsList              = 129
	OffsetAddDelegatorTx_DelegationRewardsThreshold = 137
	OffsetAddDelegatorTx_DelegationRewardsLocktime  = 141
	OffsetAddDelegatorTx_DelegationRewardsAddress   = 149
	SizeAddDelegatorTx                              = 169
)

AddDelegatorTx is the pre-Etna primary-network delegator add. Mostly superseded by AddPermissionlessDelegatorTx but still present in legacy blocks. Single delegation-rewards owner stub.

Fixed-section layout (size 173 bytes):

TxKind                       uint8  @ 0
NetworkID                    uint32 @ 1
BlockchainID                 32B    @ 5
OutsList                     8B     @ 37
InsList                      8B     @ 45
CredsList                    8B     @ 53
SigIndicesArr                8B     @ 61
SigArr                       8B     @ 69
Memo                         8B     @ 77
NodeID                       20B    @ 85
StakeStart                   uint64 @ 105
StakeEnd                     uint64 @ 113
StakeWeight                  uint64 @ 121
StakeOutsList                8B     @ 129
DelegationRewardsThreshold   uint32 @ 137
DelegationRewardsLocktime    uint64 @ 141
DelegationRewardsAddress     20B    @ 149
View Source
const (
	OffsetAPDTx_NetworkID                  = 1
	OffsetAPDTx_BlockchainID               = 5
	OffsetAPDTx_OutsList                   = 37
	OffsetAPDTx_InsList                    = 45
	OffsetAPDTx_CredsList                  = 53
	OffsetAPDTx_SigIndicesArr              = 61
	OffsetAPDTx_SigArr                     = 69
	OffsetAPDTx_Memo                       = 77
	OffsetAPDTx_NodeID                     = 85
	OffsetAPDTx_StakeStart                 = 105
	OffsetAPDTx_StakeEnd                   = 113
	OffsetAPDTx_StakeWeight                = 121
	OffsetAPDTx_Chain                      = 129
	OffsetAPDTx_StakeAssetID               = 161
	OffsetAPDTx_StakeOutsList              = 193
	OffsetAPDTx_DelegationRewardsThreshold = 201
	OffsetAPDTx_DelegationRewardsLocktime  = 205
	OffsetAPDTx_DelegationRewardsAddress   = 213
	SizeAddPermissionlessDelegatorTx       = 233
)

AddPermissionlessDelegatorTx — Etna+ permissionless delegator add. Carries a chain ID (which chain the validator is on), stake details, and a single delegation-rewards owner stub.

Fixed-section layout (size 217 bytes):

TxKind                       uint8  @ 0
NetworkID                    uint32 @ 1
BlockchainID                 32B    @ 5
OutsList                     8B     @ 37
InsList                      8B     @ 45
CredsList                    8B     @ 53
SigIndicesArr                8B     @ 61
SigArr                       8B     @ 69
Memo                         8B     @ 77
NodeID                       20B    @ 85
StakeStart                   uint64 @ 105
StakeEnd                     uint64 @ 113
StakeWeight                  uint64 @ 121
Chain                        32B    @ 129  (ids.ID — which chain the validator validates)
StakeAssetID                 32B    @ 161
StakeOutsList                8B     @ 193
DelegationRewardsThreshold   uint32 @ 201
DelegationRewardsLocktime    uint64 @ 205
DelegationRewardsAddress     20B    @ 213
View Source
const (
	OffsetAPVTx_NetworkID                       = 1
	OffsetAPVTx_BlockchainID                    = 5
	OffsetAPVTx_OutsList                        = 37
	OffsetAPVTx_InsList                         = 45
	OffsetAPVTx_CredsList                       = 53
	OffsetAPVTx_SigIndicesArr                   = 61
	OffsetAPVTx_SigArr                          = 69
	OffsetAPVTx_Memo                            = 77
	OffsetAPVTx_NodeID                          = 85
	OffsetAPVTx_StakeStart                      = 105
	OffsetAPVTx_StakeEnd                        = 113
	OffsetAPVTx_StakeWeight                     = 121
	OffsetAPVTx_StakeAssetID                    = 129
	OffsetAPVTx_StakeAmount                     = 161
	OffsetAPVTx_BLSPublicKey                    = 169
	OffsetAPVTx_BLSProofOfPossession            = OffsetAPVTx_BLSPublicKey + bls.PublicKeyLen
	OffsetAPVTx_ValidationRewardsOwnerThreshold = OffsetAPVTx_BLSProofOfPossession + bls.SignatureLen
	OffsetAPVTx_ValidationRewardsOwnerLocktime  = OffsetAPVTx_ValidationRewardsOwnerThreshold + 4
	OffsetAPVTx_ValidationRewardsOwnerAddress   = OffsetAPVTx_ValidationRewardsOwnerLocktime + 8
	OffsetAPVTx_DelegationRewardsOwnerThreshold = OffsetAPVTx_ValidationRewardsOwnerAddress + ids.ShortIDLen
	OffsetAPVTx_DelegationRewardsOwnerLocktime  = OffsetAPVTx_DelegationRewardsOwnerThreshold + 4
	OffsetAPVTx_DelegationRewardsOwnerAddress   = OffsetAPVTx_DelegationRewardsOwnerLocktime + 8
	OffsetAPVTx_DelegationShares                = OffsetAPVTx_DelegationRewardsOwnerAddress + ids.ShortIDLen
	SizeAddPermissionlessValidatorTx            = OffsetAPVTx_DelegationShares + 4
)

AddPermissionlessValidatorTx is the v3 register-permissionless-validator envelope. It carries the BaseTxFull spending state, the validator identity (NodeID + bond stake metadata + signer), and two nested Owner stubs (validation rewards owner + delegation rewards owner). Both owners are single-address stubs in v3 (matching TransferChainOwnershipTx / OutputList semantics). Multi-address owners flow through legacy.

Fixed-section layout (size 269 bytes):

TxKind                       uint8  @ 0
NetworkID                    uint32 @ 1
BlockchainID                 32B    @ 5
OutsList                     8B     @ 37
InsList                      8B     @ 45
CredsList                    8B     @ 53
SigIndicesArr                8B     @ 61
SigArr                       8B     @ 69
Memo                         8B     @ 77
NodeID                       20B    @ 85    (ids.NodeID)
StakeStart                   uint64 @ 105
StakeEnd                     uint64 @ 113
StakeWeight                  uint64 @ 121
StakeAssetID                 32B    @ 129
StakeAmount                  uint64 @ 161
BLSPublicKey                 48B    @ 169   (bls.PublicKeyLen)
BLSProofOfPossession         96B    @ 217   (bls.SignatureLen)
ValidationRewardsOwnerThresh uint32 @ 313
ValidationRewardsOwnerLT     uint64 @ 317
ValidationRewardsOwnerAddr   20B    @ 325
DelegationRewardsOwnerThresh uint32 @ 345
DelegationRewardsOwnerLT     uint64 @ 349
DelegationRewardsOwnerAddr   20B    @ 357
DelegationShares             uint32 @ 377
Size                                = 381
View Source
const (
	OffsetAddValidatorTx_NetworkID             = 1
	OffsetAddValidatorTx_BlockchainID          = 5
	OffsetAddValidatorTx_OutsList              = 37
	OffsetAddValidatorTx_InsList               = 45
	OffsetAddValidatorTx_CredsList             = 53
	OffsetAddValidatorTx_SigIndicesArr         = 61
	OffsetAddValidatorTx_SigArr                = 69
	OffsetAddValidatorTx_Memo                  = 77
	OffsetAddValidatorTx_NodeID                = 85
	OffsetAddValidatorTx_StakeStart            = 105
	OffsetAddValidatorTx_StakeEnd              = 113
	OffsetAddValidatorTx_StakeWeight           = 121
	OffsetAddValidatorTx_StakeOutsList         = 129
	OffsetAddValidatorTx_RewardsOwnerThreshold = 137
	OffsetAddValidatorTx_RewardsOwnerLocktime  = 141
	OffsetAddValidatorTx_RewardsOwnerAddress   = 149
	OffsetAddValidatorTx_DelegationShares      = 169
	SizeAddValidatorTx                         = 173
)

AddValidatorTx is the pre-Etna primary-network validator add. Mostly superseded by AddPermissionlessValidatorTx but still present in legacy blocks. Single-address rewards owner (OwnerStub fast path); multi-address callers go through legacy codec or build Owner explicitly.

Fixed-section layout (size 195 bytes):

TxKind                  uint8  @ 0
NetworkID               uint32 @ 1
BlockchainID            32B    @ 5
OutsList                8B     @ 37
InsList                 8B     @ 45
CredsList               8B     @ 53
SigIndicesArr           8B     @ 61
SigArr                  8B     @ 69
Memo                    8B     @ 77
NodeID                  20B    @ 85
StakeStart              uint64 @ 105
StakeEnd                uint64 @ 113
StakeWeight             uint64 @ 121
StakeOutsList           8B     @ 129  (sibling Outs for staked tokens)
RewardsOwnerThreshold   uint32 @ 137
RewardsOwnerLocktime    uint64 @ 141
RewardsOwnerAddress     20B    @ 149
DelegationShares        uint32 @ 169
View Source
const (
	SchemaVersionAdvanceTimeTx uint16 = 3

	OffsetAdvanceTimeTx_Time = 1 // uint64 (after TxKind@0)
	SizeAdvanceTimeTx        = 9
)

AdvanceTimeTx ZAP schema v3: TxKind discriminator + uint64 timestamp.

Wire = ZAP_HEADER (16 bytes) + Object{ TxKind: u8@0, Time: u64@1 } (9 bytes).

View Source
const (
	SchemaVersionBaseTx uint16 = 3

	OffsetBaseTx_NetworkID    = 1  // uint32
	OffsetBaseTx_BlockchainID = 5  // ids.ID (32 bytes)
	OffsetBaseTx_Memo         = 37 // bytes (offset+length, 8 bytes)
	SizeBaseTx                = 45
)

BaseTx v3 schema — TxKind + NetworkID + BlockchainID + Memo. The Outs/Ins fields of the legacy lux.BaseTx are variable-length nested-object lists and need a proper ZAP list schema; they ship in batch 3 as BaseTxFull. This minimal form is the metadata envelope every higher-level platformvm tx embeds.

Fixed-section layout (size 45 bytes):

TxKind       uint8  @ 0
NetworkID    uint32 @ 1
BlockchainID 32B    @ 5
Memo         bytes  @ 37  (offset+length pair, 8 bytes)
View Source
const (
	OffsetBaseTxFull_NetworkID     = 1
	OffsetBaseTxFull_BlockchainID  = 5
	OffsetBaseTxFull_OutsList      = 37 // list pointer (8 bytes)
	OffsetBaseTxFull_InsList       = 45 // list pointer (8 bytes)
	OffsetBaseTxFull_CredsList     = 53 // list pointer (8 bytes)
	OffsetBaseTxFull_SigIndicesArr = 61 // list pointer (8 bytes)
	OffsetBaseTxFull_SigArr        = 69 // list pointer (8 bytes)
	OffsetBaseTxFull_Memo          = 77 // bytes (8 bytes)
	SizeBaseTxFull                 = 85
)

BaseTxFull is the full P-chain spending envelope: NetworkID + BlockchainID + Outs + Ins + Credentials + Memo. Higher-level tx types (Import/Export/ AddPermissionlessValidator/CreateChain) embed this. The minimal metadata-only BaseTx (TxKindBase) remains for places that need only {NetworkID, BlockchainID, Memo} without spending state.

Fixed-section layout (size 73 bytes; uint64 reads alignment-tolerant):

TxKind              uint8  @ 0
NetworkID           uint32 @ 1
BlockchainID        32B    @ 5
OutsListRel         uint32 @ 37   (list pointer; (offset,count))
OutsListLen         uint32 @ 41
InsListRel          uint32 @ 45
InsListLen          uint32 @ 49
CredsListRel        uint32 @ 53
CredsListLen        uint32 @ 57
SigIndicesArrRel    uint32 @ 61   (shared uint32 array; InputList slices here)
SigIndicesArrLen    uint32 @ 65
SigArrRel           uint32 @ 69   (shared signature blob array; CredentialList slices)
SigArrLen           uint32 @ 73
Memo                bytes  @ 77   (relOffset + length, 8 bytes)
(fixed-section size 85; the 4 list-pointer pairs are 8 bytes each,
 stored as 4-byte rel + 4-byte length consistent with zap.Object.List)

Layout summary: header + 5 lists/arrays (each is a 4-byte relOffset and a 4-byte length, 40 bytes total for the 5 pointers) + Memo (8 bytes).

Total fixed section = 1 (TxKind) + 4 (NetworkID) + 32 (BlockchainID) + 5*8 (4 lists + 1 array pair) + 8 (Memo) = 85 bytes. But the 5 list+arr pointers are split into 5×(4+4) = 40 bytes, beginning at offset 37.

View Source
const (
	OffsetChainEntry_NameRel        = 0
	OffsetChainEntry_NameLen        = 4
	OffsetChainEntry_VMID           = 8
	OffsetChainEntry_FxIDsRel       = 40
	OffsetChainEntry_FxIDsLen       = 44
	OffsetChainEntry_GenesisDataRel = 48
	OffsetChainEntry_GenesisDataLen = 52
	OffsetChainEntry_Reserved       = 56 // [56..64) — must be zero, gated by ChainsListView.MustVerify (R6-4 + R7V8)
	SizeChainEntry                  = 64

	// FxIDSize is the wire size of one chain ID inside the FxIDs blob.
	// FxIDsLen is in BYTES; entry count = FxIDsLen / FxIDSize.
	FxIDSize = 32
)

ChainEntry is the fixed-stride wire entry of a ChainsList. Each entry pins one chain's (Name, VMID, FxIDs, GenesisData) tuple. Variable-length content (Name bytes, FxIDs blob, GenesisData bytes) lives in three sibling arrays carried as parent-tx fields; the entry stores (relativeOffset, length) cursors into them.

This mirrors the BoundEvidenceList pattern (batch 3) for orthogonal composability: a fixed-stride list payload + sibling blob arrays + type-level Bind to attach the blobs and unlock safe accessors.

Wire layout per ChainEntry (stride 64 bytes):

NameRel          uint32 @ 0        (byte offset within NameBlobs)
NameLen          uint32 @ 4
VMID             32B    @ 8        (the VM identifier)
FxIDsRel         uint32 @ 40       (byte offset within FxIDsBlobs)
FxIDsLen         uint32 @ 44       (in BYTES; entry count = Len / 32)
GenesisDataRel   uint32 @ 48       (byte offset within GenesisDataBlobs)
GenesisDataLen   uint32 @ 52
Reserved         8B     @ 56..64   (zero — future expansion: subnet flags,
                                    initial supply hint, etc.)

Stride = 64 bytes (8-byte aligned for cleanly composable List.Object reads).

View Source
const (
	OffsetConvertNetworkToL1Tx_NetworkID      = 1
	OffsetConvertNetworkToL1Tx_BlockchainID   = 5
	OffsetConvertNetworkToL1Tx_OutsList       = 37
	OffsetConvertNetworkToL1Tx_InsList        = 45
	OffsetConvertNetworkToL1Tx_CredsList      = 53
	OffsetConvertNetworkToL1Tx_SigIndicesArr  = 61
	OffsetConvertNetworkToL1Tx_SigArr         = 69
	OffsetConvertNetworkToL1Tx_Memo           = 77
	OffsetConvertNetworkToL1Tx_Chain          = 85
	OffsetConvertNetworkToL1Tx_ManagerChainID = 117
	OffsetConvertNetworkToL1Tx_Address        = 149
	OffsetConvertNetworkToL1Tx_ValidatorsList = 157
	SizeConvertNetworkToL1Tx                  = 165
)

ConvertNetworkToL1Tx — convert a network to a sovereign L1 (POST-rebrand from ConvertSubnetToL1Tx). Carries the BaseTxFull spending state plus:

  • Chain (the chain to convert; primary network ID forbidden in consumer-side syntactic verify)
  • ManagerChainID (where the L1 manager contract lives)
  • Address (chain-manager contract address, variable bytes)
  • Validators list (initial pay-as-you-go validators)

The Validators sub-list is a fixed-stride record per validator carrying (NodeID, Weight, BLSPubKey, BLSPoP, RegistrationExpiry). LP-023 batch 5 Phase D wires the real ValidatorsList primitive — previously stubbed at (0, 0). The encoding now matches the primitive in validators_list.go (180B per record, stride-clamped via Object.ListStride from zap v0.7.2).

Fixed-section layout (size 165 bytes):

TxKind                  uint8  @ 0
NetworkID               uint32 @ 1
BlockchainID            32B    @ 5
OutsList                8B     @ 37
InsList                 8B     @ 45
CredsList               8B     @ 53
SigIndicesArr           8B     @ 61
SigArr                  8B     @ 69
Memo                    8B     @ 77
Chain                   32B    @ 85
ManagerChainID          32B    @ 117
Address                 8B     @ 149  (variable bytes)
ValidatorsList          8B     @ 157  (fixed-stride 180B records)
View Source
const (
	OffsetCreateChainTx_NetworkID       = 1
	OffsetCreateChainTx_BlockchainID    = 5
	OffsetCreateChainTx_OutsList        = 37
	OffsetCreateChainTx_InsList         = 45
	OffsetCreateChainTx_CredsList       = 53
	OffsetCreateChainTx_SigIndicesArr   = 61
	OffsetCreateChainTx_SigArr          = 69
	OffsetCreateChainTx_Memo            = 77
	OffsetCreateChainTx_ParentNetwork   = 85
	OffsetCreateChainTx_VMID            = 117
	OffsetCreateChainTx_OwnerThreshold  = 149
	OffsetCreateChainTx_OwnerLocktime   = 153
	OffsetCreateChainTx_OwnerAddress    = 161
	OffsetCreateChainTx_WarpMessageHash = OffsetCreateChainTx_OwnerAddress + ids.ShortIDLen
	OffsetCreateChainTx_GenesisData     = OffsetCreateChainTx_WarpMessageHash + 32
	SizeCreateChainTx                   = OffsetCreateChainTx_GenesisData + 8
)

CreateChainTx is the v3 create-blockchain envelope. It carries the BaseTxFull spending state, the parent network ID, the child VM ID, an optional genesis-data byte blob (variable; lives in the variable section), a single-address Owner stub, and the SHA-256 hash of the corresponding Warp message (when this CreateChain was originated via cross-network commit). The Warp message body itself is NOT embedded — only its hash — because the body lives in the signed Warp envelope outside this tx.

Fixed-section layout (size 173 bytes):

TxKind             uint8  @ 0
NetworkID          uint32 @ 1
BlockchainID       32B    @ 5
OutsList           8B     @ 37
InsList            8B     @ 45
CredsList          8B     @ 53
SigIndicesArr      8B     @ 61
SigArr             8B     @ 69
Memo               8B     @ 77
ParentNetwork      32B    @ 85    (ids.ID; the parent network)
VMID               32B    @ 117   (ids.ID; the VM identifier)
OwnerThreshold     uint32 @ 149
OwnerLocktime      uint64 @ 153
OwnerAddress       20B    @ 161
WarpMessageHash    32B    @ 181   (sha256 of the originating Warp msg; zero if none)
GenesisData        bytes  @ 213   (offset+length; variable)
Size                      = 221
View Source
const (
	OffsetCreateNetworkTx_NetworkID      = 1
	OffsetCreateNetworkTx_BlockchainID   = 5
	OffsetCreateNetworkTx_OutsList       = 37
	OffsetCreateNetworkTx_InsList        = 45
	OffsetCreateNetworkTx_CredsList      = 53
	OffsetCreateNetworkTx_SigIndicesArr  = 61
	OffsetCreateNetworkTx_SigArr         = 69
	OffsetCreateNetworkTx_Memo           = 77
	OffsetCreateNetworkTx_OwnerThreshold = 85
	OffsetCreateNetworkTx_OwnerLocktime  = 89
	OffsetCreateNetworkTx_OwnerAddress   = 97
	SizeCreateNetworkTx                  = 117
)

CreateNetworkTx — create a new network/subnet (POST-rebrand: this is the rebranded CreateSubnetTx). Carries the BaseTxFull spending state plus a single-address owner stub authorizing the network manager.

Fixed-section layout (size 113 bytes):

TxKind             uint8  @ 0
NetworkID          uint32 @ 1
BlockchainID       32B    @ 5
OutsList           8B     @ 37
InsList            8B     @ 45
CredsList          8B     @ 53
SigIndicesArr      8B     @ 61
SigArr             8B     @ 69
Memo               8B     @ 77
OwnerThreshold     uint32 @ 85
OwnerLocktime      uint64 @ 89
OwnerAddress       20B    @ 97
View Source
const (
	OffsetCreateSovereignL1Tx_NetworkID        = 1
	OffsetCreateSovereignL1Tx_BlockchainID     = 5
	OffsetCreateSovereignL1Tx_OutsList         = 37
	OffsetCreateSovereignL1Tx_InsList          = 45
	OffsetCreateSovereignL1Tx_CredsList        = 53
	OffsetCreateSovereignL1Tx_SigIndicesArr    = 61
	OffsetCreateSovereignL1Tx_SigArr           = 69
	OffsetCreateSovereignL1Tx_Memo             = 77
	OffsetCreateSovereignL1Tx_OwnerThreshold   = 85
	OffsetCreateSovereignL1Tx_OwnerLocktime    = 89
	OffsetCreateSovereignL1Tx_OwnerAddress     = 97
	OffsetCreateSovereignL1Tx_ManagerChainIdx  = 117
	OffsetCreateSovereignL1Tx_ManagerAddress   = 121
	OffsetCreateSovereignL1Tx_ValidatorsList   = 129
	OffsetCreateSovereignL1Tx_ChainsList       = 137
	OffsetCreateSovereignL1Tx_NameBlobs        = 145
	OffsetCreateSovereignL1Tx_FxIDsBlobs       = 153
	OffsetCreateSovereignL1Tx_GenesisDataBlobs = 161
	SizeCreateSovereignL1Tx                    = 193
)

CreateSovereignL1Tx atomically registers a sovereign L1 on P-chain. Combines CreateNetwork + AddChainValidator(*N) + CreateChain(*K) + ConvertNetworkToL1 into one atomic commit. See legacy /vms/platformvm/txs/create_sovereign_l1_tx.go for full semantics.

LP-023 batch 5 (Phase C+D): this v3 form now supports MULTI-CHAIN L1s (EVM + DEX + FHE + …) via the ChainsList primitive and carries the real initial-validator set via ValidatorsList. The previous batch-4 stub pinned a single (VMID, blockchainID) pair; that field is gone.

Fixed-section layout (size 193 bytes):

TxKind                  uint8  @ 0
NetworkID               uint32 @ 1
BlockchainID            32B    @ 5
OutsList                8B     @ 37
InsList                 8B     @ 45
CredsList               8B     @ 53
SigIndicesArr           8B     @ 61
SigArr                  8B     @ 69
Memo                    8B     @ 77
OwnerThreshold          uint32 @ 85
OwnerLocktime           uint64 @ 89
OwnerAddress            20B    @ 97
ManagerChainIdx         uint32 @ 117
ManagerAddress          8B     @ 121  (variable bytes)
ValidatorsList          8B     @ 129  (fixed-stride 180B records)
ChainsList              8B     @ 137  (fixed-stride 64B entries)
NameBlobs               8B     @ 145  (sibling for ChainsList.Name)
FxIDsBlobs              8B     @ 153  (sibling for ChainsList.FxIDs)
GenesisDataBlobs        8B     @ 161  (sibling for ChainsList.GenesisData)
Reserved                24B    @ 169..193 (zero — future expansion)
View Source
const (
	OffsetCredential_SigsStart = 0 // uint32
	OffsetCredential_SigsCount = 4 // uint32
	SizeCredential             = 16
)

Credential is the primitive entry of a CredentialList. Each entry is a fixed-stride record describing a slice into the parent tx's shared SignatureArray (which holds SigBlobSize-byte signatures concatenated). One credential corresponds to one input (1:1 by index).

Wire layout per entry (stride 16 bytes):

SigsStart  uint32 @ 0     (index into shared SignatureArray)
SigsCount  uint32 @ 4     (number of signatures for this credential)
Reserved   8B     @ 8     (reserved-zero; 8-aligned stride)
View Source
const (
	SchemaVersionDisableL1ValidatorTx uint16 = 3

	OffsetDisableL1ValidatorTx_ValidationID = 1 // 32 bytes
	SizeDisableL1ValidatorTx                = 33
)

DisableL1ValidatorTx v3 schema — TxKind + ValidationID.

Disables an L1 validator. The validator's stake is unbonded and removed from the active set. Once disabled the validator can be re-registered via a fresh RegisterL1ValidatorTx.

Fixed-section layout (size 33 bytes):

TxKind         uint8 @ 0
ValidationID   32B   @ 1
View Source
const (
	OffsetEvidenceEntry_Height        = 0  // uint64
	OffsetEvidenceEntry_EvidenceType  = 8  // uint8
	OffsetEvidenceEntry_MessageARel   = 12 // uint32 (byte offset within MessageBlobs)
	OffsetEvidenceEntry_MessageALen   = 16 // uint32
	OffsetEvidenceEntry_SignatureARel = 20 // uint32
	OffsetEvidenceEntry_SignatureALen = 24 // uint32
	OffsetEvidenceEntry_MessageBRel   = 28 // uint32
	OffsetEvidenceEntry_MessageBLen   = 32 // uint32
	OffsetEvidenceEntry_SignatureBRel = 36 // uint32
	OffsetEvidenceEntry_SignatureBLen = 40 // uint32
	SizeEvidenceEntry                 = 48
)

EvidenceEntry is the primitive entry of an EvidenceList. Each entry pins the slashable height + evidence type + indices into shared message-blob and signature-blob arrays carried as sibling fields of the parent tx. Variable-length message/signature bytes live in the shared arrays so the list itself stays fixed-stride.

Wire layout per entry (stride 40 bytes; uint64 reads alignment-tolerant):

Height           uint64 @ 0
EvidenceType     uint8  @ 8
MessageARel      uint32 @ 12   (index into shared MessageBlobs)
MessageALen      uint32 @ 16
SignatureARel    uint32 @ 20
SignatureALen    uint32 @ 24
MessageBRel      uint32 @ 28
MessageBLen      uint32 @ 32
SignatureBRel    uint32 @ 36   (single 32-bit field; second is in same entry)
SignatureBLen    uint32 @ 40
Reserved         pad to stride 48

Actually 40-byte width is too cramped; bump stride to 48 for the two message + two signature index pairs. The MessageBlobs and SignatureBlobs shared arrays are length-prefixed bytes lists; entries index them by (start byte, length) per blob.

Final stride: 48 bytes.

View Source
const (
	OffsetExportTx_NetworkID          = 1
	OffsetExportTx_BlockchainID       = 5
	OffsetExportTx_OutsList           = 37
	OffsetExportTx_InsList            = 45
	OffsetExportTx_CredsList          = 53
	OffsetExportTx_SigIndicesArr      = 61
	OffsetExportTx_SigArr             = 69
	OffsetExportTx_Memo               = 77
	OffsetExportTx_DestinationNetwork = 85
	OffsetExportTx_ExportedOutsStart  = 117
	OffsetExportTx_ExportedOutsCount  = 121
	SizeExportTx                      = 125
)

ExportTx is the v3 cross-chain export: send funds from this chain to a destination chain. The Outs list carries BOTH local change outputs and the exported outputs to the destination chain in a single fixed-stride array; ExportedOutsStart / ExportedOutsCount mark the exported slice within. Local Outs occupy positions [0, ExportedOutsStart); exported Outs occupy [ExportedOutsStart, ExportedOutsStart+ExportedOutsCount).

Fixed-section layout (size 125 bytes):

TxKind                  uint8  @ 0
NetworkID               uint32 @ 1
BlockchainID            32B    @ 5
OutsList                8B     @ 37  (combined: local change + exported)
InsList                 8B     @ 45  (local fee + funding inputs)
CredsList               8B     @ 53
SigIndicesArr           8B     @ 61
SigArr                  8B     @ 69
Memo                    8B     @ 77
DestinationNetwork      32B    @ 85  (chain the exports flow to)
ExportedOutsStart       uint32 @ 117 (index into Outs list)
ExportedOutsCount       uint32 @ 121
View Source
const (
	OffsetImportTx_NetworkID        = 1
	OffsetImportTx_BlockchainID     = 5
	OffsetImportTx_OutsList         = 37
	OffsetImportTx_InsList          = 45
	OffsetImportTx_CredsList        = 53
	OffsetImportTx_SigIndicesArr    = 61
	OffsetImportTx_SigArr           = 69
	OffsetImportTx_Memo             = 77
	OffsetImportTx_SourceNetwork    = 85
	OffsetImportTx_ImportedInsStart = 117 // uint32 (index into Ins list)
	OffsetImportTx_ImportedInsCount = 121 // uint32
	SizeImportTx                    = 125
)

ImportTx is the v3 cross-chain import: pull funds from a source chain via imported UTXOs. The Ins list carries BOTH local fee-paying inputs and the remote (imported) inputs in a single fixed-stride array; the ImportedInsStart / ImportedInsCount header fields identify the imported slice within. This keeps the SigIndicesArray / SignatureArray single shared arrays across all inputs without re-base bookkeeping. Local Ins occupy positions [0, ImportedInsStart); imported Ins occupy [ImportedInsStart, ImportedInsStart+ImportedInsCount).

Fixed-section layout (size 93 bytes):

TxKind                 uint8  @ 0
NetworkID              uint32 @ 1
BlockchainID           32B    @ 5
OutsList               8B     @ 37
InsList                8B     @ 45   (combined: local + imported)
CredsList              8B     @ 53
SigIndicesArr          8B     @ 61
SigArr                 8B     @ 69
Memo                   8B     @ 77
SourceNetwork          32B    @ 85   (...wait, that's 117. Re-do.)

Actually wait. 85 + 32 = 117. Plus ImportedInsStart/Count (8) = 125.

Re-layout to keep TxKind@0 alignment and end size 125 bytes:

View Source
const (
	SchemaVersionIncreaseL1ValidatorBalanceTx uint16 = 3

	OffsetIncreaseL1ValidatorBalanceTx_ValidationID = 1  // 32 bytes
	OffsetIncreaseL1ValidatorBalanceTx_Balance      = 33 // uint64
	SizeIncreaseL1ValidatorBalanceTx                = 41
)

IncreaseL1ValidatorBalanceTx v3 schema — TxKind + ValidationID + Balance.

Tops up the continuous-fee balance for an L1 validator without changing its stake weight or nonce.

Fixed-section layout (size 41 bytes):

TxKind         uint8  @ 0
ValidationID   32B    @ 1
Balance        uint64 @ 33
View Source
const (
	OffsetTransferableInput_TxID            = 0
	OffsetTransferableInput_OutputIndex     = 32 // uint32
	OffsetTransferableInput_AssetID         = 36 // 32B
	OffsetTransferableInput_Amount          = 68 // uint64
	OffsetTransferableInput_SigIndicesStart = 76 // uint32 (index into shared array)
	OffsetTransferableInput_SigIndicesCount = 80 // uint32 (slice length)
	SizeTransferableInput                   = 88
)

TransferableInput is the primitive entry of an InputList. Each entry is a fixed-stride record carrying the spent UTXO ID, the asset identifier, the amount being spent, and a slice [SigIndicesStart, SigIndicesStart+ SigIndicesCount) into a shared SigIndices uint32 array carried as a sibling field of the parent transaction object.

Wire layout per entry (stride 88 bytes; uint64 reads are alignment-tolerant so no padding):

TxID              32B    @ 0     (ids.ID; UTXO.TxID)
OutputIndex       uint32 @ 32
AssetID           32B    @ 36    (ids.ID)
Amount            uint64 @ 68
SigIndicesStart   uint32 @ 76    (offset into shared SigIndices array)
SigIndicesCount   uint32 @ 80    (length of slice)
Reserved          4B     @ 84    (reserved-zero; 8-aligned stride 88)

Companion field on the parent: SigIndices uint32 list of total length sum(input[i].SigIndicesCount). Each input's signature-index slice is SigIndices[Start : Start+Count].

View Source
const (
	OffsetTransferableOutput_AssetID      = 0
	OffsetTransferableOutput_Amount       = 32 // uint64
	OffsetTransferableOutput_Threshold    = 40 // uint32
	OffsetTransferableOutput_Locktime     = 44 // uint64
	OffsetTransferableOutput_OwnerAddress = 52 // 20B
	SizeTransferableOutput                = 96 // stride (with reserved-zero tail)
)

TransferableOutput is the primitive entry of an OutputList. Each entry is a fixed-stride record carrying an asset identifier, an amount, a threshold, a locktime, and a single owner address (the v3 stub form used while the multi-address Owner schema is pending). Multi-address output owners go through the legacy codec gate until the BAddressList primitive ships.

Wire layout per entry (size 96 bytes, tightly packed; uint64 reads are alignment-tolerant so no padding):

AssetID        32B    @ 0     (ids.ID)
Amount         uint64 @ 32
Threshold      uint32 @ 40
Locktime       uint64 @ 44
OwnerAddress   20B    @ 52    (ids.ShortID, single addr v3 stub)
Reserved       8B     @ 72    (reserved-zero; future Owner pointer)
_              16B    @ 80    (alignment slack for stride 96; reserved-zero)

Stride is 96 bytes (= ceil(80 + 0) padded to 8-aligned 96). Tightly-packed last-field-ends-at-80 would be 80 but list strides are kept at a natural-aligned multiple to keep zap.List.Object(i, stride) arithmetic branch-free across architectures.

View Source
const (
	OffsetOwnerHeader_Threshold   = 0
	OffsetOwnerHeader_Locktime    = 4
	OffsetOwnerHeader_AddressList = 12
	SizeOwnerHeader               = 20
)

Owner is the multi-address output owner. It composes a threshold + locktime + a variable AddressList. Stride for the AddressList lives in the same buffer's variable section; the parent object's fixed section carries (threshold, locktime, AddressList ptr).

Wire layout per Owner header (size 16 bytes; the AddressList itself lives in the variable section pointed-to by the list pointer):

Threshold       uint32 @ 0
Locktime        uint64 @ 4
AddressList     8B     @ 12   (4-byte relOffset + 4-byte length)

Total header = 20 bytes. The Owner header is embedded INLINE in the parent tx's fixed section. Variable-section addresses are appended to the parent's variable area by WriteOwner.

Design call: OwnerStub remains the canonical single-address path (zero-alloc, 32 bytes total). Owner is used ONLY when len(Addresses) >= 2. NewOwner refuses the single-address case (ErrOwnerSingleAddrUseStub) so callers must consciously pick the right primitive. This forces:

  • The common case stays in the fast path (OwnerStub, 32B inline).
  • The multi-sig case carries the multi-address overhead explicitly.
  • No silent fallback; the type system makes the choice load-bearing.
View Source
const (
	SchemaVersionRegisterL1ValidatorTx uint16 = 3

	OffsetRegisterL1ValidatorTx_ValidationID            = 1
	OffsetRegisterL1ValidatorTx_BLSPublicKey            = OffsetRegisterL1ValidatorTx_ValidationID + 32
	OffsetRegisterL1ValidatorTx_ProofOfPossession       = OffsetRegisterL1ValidatorTx_BLSPublicKey + bls.PublicKeyLen
	OffsetRegisterL1ValidatorTx_Expiry                  = OffsetRegisterL1ValidatorTx_ProofOfPossession + bls.SignatureLen
	OffsetRegisterL1ValidatorTx_RemainingBalanceOwnerID = OffsetRegisterL1ValidatorTx_Expiry + 8
	SizeRegisterL1ValidatorTx                           = OffsetRegisterL1ValidatorTx_RemainingBalanceOwnerID + 32
)

RegisterL1ValidatorTx v3 schema — TxKind + ValidationID + Signer (BLS pubkey + PoP) + Expiry + RemainingBalanceOwnerID. The legacy struct's Message is a Warp payload (variable-length addressed-call envelope) and RemainingBalanceOwner is an OutputOwners with a variable AddressIDs list — both ship as proper list/object schemas in batch 3. This v3 fixes the foundational identity fields validators look up on every block.

Fixed-section layout (size 217 bytes):

TxKind                    uint8  @ 0
ValidationID              32B    @ 1
BLSPublicKey              48B    @ 33    (bls.PublicKeyLen)
ProofOfPossession         96B    @ 81    (bls.SignatureLen)
Expiry                    uint64 @ 177
RemainingBalanceOwnerID   ids.ID @ 185   (placeholder 32B, full Owner in batch 3)
View Source
const (
	SchemaVersionRemoveChainValidatorTx uint16 = 3

	OffsetRemoveChainValidatorTx_NodeID  = 1
	OffsetRemoveChainValidatorTx_Network = OffsetRemoveChainValidatorTx_NodeID + ids.ShortIDLen
	SizeRemoveChainValidatorTx           = OffsetRemoveChainValidatorTx_Network + 32
)

RemoveChainValidatorTx v3 schema — TxKind + NodeID (20B) + Network (32B).

Legacy struct also has ChainAuth (verify.Verifiable credential) which lives outside the unsigned-tx bytes in the signed wrapper — the unsigned encoding here pins only the identity tuple the executor matches against state.

Fixed-section layout (size 53 bytes):

TxKind  uint8 @ 0
NodeID  20B   @ 1     (ids.NodeID)
Network 32B   @ 21    (ids.ID)
View Source
const (
	SchemaVersionRewardValidatorTx uint16 = 3

	OffsetRewardValidatorTx_TxID = 1 // ids.ID (32 bytes), after TxKind@0
	SizeRewardValidatorTx        = 33
)

RewardValidatorTx v3 schema — TxKind + 32-byte TxID. Issued by the chain at the end of every validator's stake period to distribute the reward.

View Source
const (
	SchemaVersionSetL1ValidatorWeightTx uint16 = 3

	OffsetSetL1ValidatorWeightTx_ValidationID = 1  // 32 bytes
	OffsetSetL1ValidatorWeightTx_Nonce        = 33 // uint64
	OffsetSetL1ValidatorWeightTx_Weight       = 41 // uint64
	SizeSetL1ValidatorWeightTx                = 49
)

SetL1ValidatorWeightTx v3 schema — TxKind + ValidationID + Nonce + Weight.

Used to adjust the stake weight of an L1 validator without a full re-register cycle. The Nonce is a strict monotonic counter scoped to the ValidationID, preventing replay.

Fixed-section layout (size 49 bytes):

TxKind         uint8  @ 0
ValidationID   32B    @ 1
Nonce          uint64 @ 33
Weight         uint64 @ 41
View Source
const (
	SchemaVersionSlashValidatorTx uint16 = 3

	OffsetSlashValidatorTx_NodeID          = 1
	OffsetSlashValidatorTx_Network         = OffsetSlashValidatorTx_NodeID + ids.ShortIDLen
	OffsetSlashValidatorTx_SlashPercentage = OffsetSlashValidatorTx_Network + 32
	SizeSlashValidatorTx                   = OffsetSlashValidatorTx_SlashPercentage + 4
)

SlashValidatorTx v3 schema — TxKind + NodeID (20B) + Network (32B) + SlashPercentage.

The legacy struct also carries an Evidence object (height, type, two message/signature pairs). Evidence is variable-length nested bytes and ships with the proper list/object schema in batch 3. SlashPercentage is included here as a uint32 because it's fixed-size and the executor needs it before evaluating the evidence.

Fixed-section layout (size 57 bytes):

TxKind          uint8  @ 0
NodeID          20B    @ 1     (ids.NodeID, ShortIDLen)
Network         32B    @ 21    (ids.ID)
SlashPercentage uint32 @ 53
View Source
const (
	SchemaVersionTransferChainOwnershipTx uint16 = 3

	OffsetTransferChainOwnershipTx_Chain          = 1
	OffsetTransferChainOwnershipTx_OwnerThreshold = 33
	OffsetTransferChainOwnershipTx_OwnerLocktime  = 37
	OffsetTransferChainOwnershipTx_OwnerAddress   = 45
	SizeTransferChainOwnershipTx                  = OffsetTransferChainOwnershipTx_OwnerAddress + ids.ShortIDLen
)

TransferChainOwnershipTx v3 schema — TxKind + Chain + single-address Owner.

The legacy struct's Owner is an fx.Owner interface — almost always *secp256k1fx.OutputOwners with {Threshold uint32, Locktime uint64, AddressIDs []ids.ShortID}. The variable AddressIDs list ships with the proper schema in batch 3. The v3 form pins the single most common configuration: threshold-1 / locktime-0 / single owner address. Callers that need richer Owner shapes still have the legacy encoder available behind LUXD_ENABLE_LEGACY_CODEC.

The legacy struct also has ChainAuth (verify.Verifiable, a credential proof produced by the signer). This is itself signature material that rides outside the unsigned-tx bytes in the signed wrapper, so it stays in the signed-tx schema (separate from the unsigned encoding here).

Fixed-section layout (size 69 bytes):

TxKind         uint8  @ 0
Chain          32B    @ 1     (ids.ID)
OwnerThreshold uint32 @ 33
OwnerLocktime  uint64 @ 37
OwnerAddress   20B    @ 45    (ids.ShortID; single owner v3 stub)

Fields are tightly packed; uint64 reads via binary.LittleEndian.Uint64 are alignment-tolerant so no natural-alignment padding is required.

View Source
const (
	OffsetTransformChainTx_NetworkID                = 1
	OffsetTransformChainTx_BlockchainID             = 5
	OffsetTransformChainTx_OutsList                 = 37
	OffsetTransformChainTx_InsList                  = 45
	OffsetTransformChainTx_CredsList                = 53
	OffsetTransformChainTx_SigIndicesArr            = 61
	OffsetTransformChainTx_SigArr                   = 69
	OffsetTransformChainTx_Memo                     = 77
	OffsetTransformChainTx_Chain                    = 85
	OffsetTransformChainTx_AssetID                  = 117
	OffsetTransformChainTx_InitialSupply            = 149
	OffsetTransformChainTx_MaximumSupply            = 157
	OffsetTransformChainTx_MinConsumptionRate       = 165
	OffsetTransformChainTx_MaxConsumptionRate       = 173
	OffsetTransformChainTx_MinValidatorStake        = 181
	OffsetTransformChainTx_MaxValidatorStake        = 189
	OffsetTransformChainTx_MinStakeDuration         = 197
	OffsetTransformChainTx_MaxStakeDuration         = 201
	OffsetTransformChainTx_MinDelegationFee         = 205
	OffsetTransformChainTx_MinDelegatorStake        = 209
	OffsetTransformChainTx_MaxValidatorWeightFactor = 217
	OffsetTransformChainTx_UptimeRequirement        = 218
	SizeTransformChainTx                            = 222
)

TransformChainTx — transform chain configuration (POST-rebrand from TransformSubnetTx). Carries economic parameters for converting a chain's validator/delegator economics. ChainAuth lives in the signed wrapper, not here.

Fixed-section layout (size 191 bytes):

TxKind                       uint8  @ 0
NetworkID                    uint32 @ 1
BlockchainID                 32B    @ 5
OutsList                     8B     @ 37
InsList                      8B     @ 45
CredsList                    8B     @ 53
SigIndicesArr                8B     @ 61
SigArr                       8B     @ 69
Memo                         8B     @ 77
Chain                        32B    @ 85
AssetID                      32B    @ 117
InitialSupply                uint64 @ 149
MaximumSupply                uint64 @ 157
MinConsumptionRate           uint64 @ 165
MaxConsumptionRate           uint64 @ 173
MinValidatorStake            uint64 @ 181
MaxValidatorStake            uint64 @ 189
MinStakeDuration             uint32 @ 197
MaxStakeDuration             uint32 @ 201
MinDelegationFee             uint32 @ 205
MinDelegatorStake            uint64 @ 209
MaxValidatorWeightFactor     uint8  @ 217
UptimeRequirement            uint32 @ 218
View Source
const (
	OffsetValidatorRecord_NodeID             = 0
	OffsetValidatorRecord_Weight             = 20
	OffsetValidatorRecord_BLSPubKey          = 28
	OffsetValidatorRecord_BLSPoP             = 76
	OffsetValidatorRecord_RegistrationExpiry = 172
	SizeValidatorRecord                      = 180

	BLSPubKeySize = 48
	BLSPoPSize    = 96
)

ValidatorRecord is the fixed-stride wire entry of a ValidatorsList. One initial validator per record carrying:

  • NodeID 20 B (ids.NodeID)
  • Weight 8 B (uint64; stake amount)
  • BLSPubKey 48 B (BLS12-381 G1 compressed)
  • BLSPoP 96 B (BLS proof-of-possession, G2 compressed)
  • RegistrationExpiry 8 B (unix timestamp; validator must register on the new L1 before this expiry) = 180 B per record (no sibling arrays needed; everything fixed-size).

Wire layout per ValidatorRecord (stride 180 bytes; 4-byte aligned):

NodeID                  20B    @ 0
Weight                  uint64 @ 20
BLSPubKey               48B    @ 28
BLSPoP                  96B    @ 76
RegistrationExpiry      uint64 @ 172

Total = 180 bytes.

View Source
const (
	OffsetWarpMessage_SourceNetwork = 0
	OffsetWarpMessage_Payload       = 32 // bytes (relOffset + length, 8 bytes)
	SizeWarpMessage                 = 40
)

WarpMessage is an embedded cross-chain message payload. It carries the 32-byte source-network identifier plus the addressed-call payload bytes. The signature aggregation lives outside the unsigned-tx encoding (in the signed-tx wrapper); this primitive captures only the unsigned content that hashes into the messageID.

Fixed-section layout (40 bytes; the Payload Bytes lives in the variable section after the fixed section, identical to BaseTx.Memo):

SourceNetwork  32B    @ 0    (ids.ID; the source network identifier)
Payload        bytes  @ 32   (offset+length pair, 8 bytes)

Total fixed-section size: 40. Payload Bytes pointer is unsigned/forward per the F1 contract.

View Source
const OffsetTxKind = 0

OffsetTxKind is the fixed wire position of the discriminator. Every zap_native fixed section reserves byte 0 for TxKind.

View Source
const SigBlobSize = secp256k1.SignatureLen // 65

SigBlobSize is the canonical secp256k1 signature length (65 bytes: 64-byte signature + 1-byte recovery id). Credentials in the v3 schema use this fixed stride for the shared signature array. Post-quantum credentials (ML-DSA) travel through the legacy codec gate until their dedicated v3 schema lands.

View Source
const SizeSigIndex = 4

SizeSigIndex is the stride of a single uint32 sig index in the shared SigIndices array. Used by SigIndicesArrayView's ListStride clamp.

View Source
const ZAPActivationUnix uint64 = 0

ZAPActivationUnix is the unix timestamp at which P-chain wire format switches from legacy linearcodec (CodecVersionV0/V1) to native ZAP. The switch governs the WRITE path: post-activation blocks MUST be ZAP-encoded. Validator coordination is documented in LP-023.

Value: 0 — ZAP is mandatory from genesis. The legacy codec is only reachable via the LUXD_ENABLE_LEGACY_CODEC=1 dev knob for reading pre-2026-06-02 historical P-chain bytes. New deployments, fresh syncs, and all production binaries from v1.28.19 onward are ZAP-only by construction. The previous forward-dated 1782604800 (2026-07-01) value is dead — see LP-023 ZAP-native activation cutover (2026-06-02).

Variables

View Source
var (
	// ErrOwnerThresholdZero is returned when threshold == 0. A zero
	// threshold semantically means "no signature required" which is an
	// authorization bypass. The single-address fast path (OwnerStub) is
	// also gated by this — there is no legitimate threshold=0 owner.
	ErrOwnerThresholdZero = errors.New(
		"zap_native: Owner.Threshold must be > 0; threshold=0 disables authorization",
	)

	// ErrOwnerThresholdExceedsAddrs is returned when threshold >
	// Addresses.Len(). An unsatisfiable gate (DoS — spend can never
	// authorize) and on signed-arithmetic consumers can underflow.
	ErrOwnerThresholdExceedsAddrs = errors.New(
		"zap_native: Owner.Threshold exceeds Addresses.Len() — unsatisfiable signer quorum",
	)

	// ErrOwnerAddrsEmpty is returned when Addresses.Len() == 0. With no
	// signer set the gate is undefined; combined with R4V7's threshold=0
	// case this would silently allow any tx to spend.
	ErrOwnerAddrsEmpty = errors.New(
		"zap_native: Owner.Addresses is empty — signer set undefined",
	)

	// ErrOwnerAddrZero is returned by Owner.SyntacticVerify when one or
	// more addresses in the list is the zero ShortID. This closes R4V3:
	// a malicious wire-encoded list with honest overcount (length field
	// claims M, actual entries N < M) returns zero-padded phantom
	// entries at i >= N for some buffer geometries. Treating those as
	// valid signers is an auth bypass. Fail-closed at the gate.
	ErrOwnerAddrZero = errors.New(
		"zap_native: Owner.Addresses contains the zero ShortID — phantom signer",
	)
)

Owner SyntacticVerify error set (LP-023 Red round 4, R4V7 — executor side gate). The wire layer accepts any (threshold, locktime, addrlist) triple as long as the buffer geometry passes the ListStride clamp; a malicious encoder can publish threshold=0 (no-op gate) or threshold > len(Addresses) (unsatisfiable gate) or empty Addresses (undefined). The executor MUST call SyntacticVerify before trusting the Owner.

View Source
var (
	// ErrZeroValidators is returned when the initial-validator set of a
	// CreateSovereignL1Tx is empty. A zero-validator L1 halts consensus
	// at activation (no quorum can ever be reached). Reject at the wire
	// boundary, not at chain bring-up time.
	ErrZeroValidators = errors.New(
		"zap_native: Validators list is empty — L1 cannot bootstrap consensus",
	)

	// ErrZeroChains is returned when the chains-to-create list of a
	// CreateSovereignL1Tx is empty. An L1 with no chains has no surface;
	// the tx commits no state. Reject as malformed.
	ErrZeroChains = errors.New(
		"zap_native: Chains list is empty — L1 has no chains to create",
	)

	// ErrValidatorWeightZero is returned when any validator entry has a
	// stake weight of zero. A zero-weight validator contributes nothing
	// to quorum, so it is either a constructor mistake or a deliberate
	// quorum-skewing attack (filler entries that pad the count but do
	// not contribute to the threshold).
	ErrValidatorWeightZero = errors.New(
		"zap_native: validator Weight must be > 0; zero-weight validator skews quorum",
	)

	// ErrBadBLSPoP is returned when any validator entry's BLS
	// proof-of-possession fails to verify against the embedded BLS
	// public key. The pairing check binds the BLS keypair to the
	// pubkey value; without it an adversary could substitute an
	// arbitrary pubkey/PoP pair and seize validator authority on the
	// new L1 at registration time. Wire layer is opaque about pairing
	// validity; this gate is the only place it fires before the
	// executor commits the validator set.
	ErrBadBLSPoP = errors.New(
		"zap_native: validator BLSPoP failed pairing verification",
	)

	// ErrMalformedFxIDsLen is returned when a chain entry's FxIDsLen is
	// not an exact multiple of FxIDSize. The wire layer's
	// BoundChainEntry.FxIDs silently returns nil for this case
	// (fail-closed at access time), but a downstream consumer that
	// looks at .FxIDsRange() length directly — or treats the empty
	// slice as "no FxIDs allowed" — could be coerced into accepting a
	// tx with a malformed fx-id geometry. Reject at the wire boundary.
	ErrMalformedFxIDsLen = errors.New(
		"zap_native: ChainEntry.FxIDsLen must be an exact multiple of FxIDSize (32)",
	)

	// ErrReservedNonZero is returned when a ChainEntry's RESERVED bytes
	// at wire offsets [56..64) are not all zero. The writer
	// (WriteChainsList) emits zero for these 8 bytes — they are reserved
	// for future expansion (subnet flags, initial supply hint, etc.).
	// Today the parser ignores them, which means an adversary can
	// smuggle arbitrary state inside what consensus considers an empty
	// region. If a v4 parser later attaches meaning to those bytes (e.g.
	// adds a flag at offset 56), every v3 tx that smuggled non-zero bytes
	// becomes a silent wire-fork: the same tx now means two different
	// things on v3 vs v4 nodes. Reject at the wire boundary now, before
	// any tx is ever accepted with non-zero reserved bytes — that pins
	// the upgrade-safe invariant for all future expansions.
	ErrReservedNonZero = errors.New(
		"zap_native: ChainEntry RESERVED bytes [56..64) must be zero",
	)
)

R6V4 + R6V3 + R6V5 typed errors. Each is wrapped by CreateSovereignL1Tx.Verify with tx-kind context; consumers match via errors.Is.

View Source
var ErrLegacyCodecDisabled = errors.New("zap_native: legacy codec not enabled (set LUXD_ENABLE_LEGACY_CODEC=1 to read pre-activation blocks)")

ErrLegacyCodecDisabled is returned by legacy-path parsers when the operator has not enabled legacy codec support via the LUXD_ENABLE_LEGACY_CODEC env var. Native ZAP is the default; legacy is opt-in.

View Source
var ErrOwnerSingleAddrUseStub = errors.New(
	"zap_native: Owner requires len(Addresses) >= 2; use OwnerStub for single-address fast path",
)

ErrOwnerSingleAddrUseStub is returned by NewOwner when the input addresses slice has length 1 — callers should use OwnerStub directly for the zero-alloc fast path. Multi-address Owner exists only when threshold > 1 or multiple co-signers are required.

View Source
var ErrWrongSchemaVersion = errors.New("zap_native: wire version does not match v3 schema (Version2)")

ErrWrongSchemaVersion is returned by Wrap*Tx when the buffer's ZAP wire header version is not Version2. v3 platformvm tx schemas live exclusively under Version2; v1-header buffers (legacy v2 platformvm schema) collide with the v3 TxKind discriminator (e.g. NetworkID=11 byte 0 == TxKindBaseFull) and must be rejected before any field interpretation. RED-MEDIUM-1 (LP-023 v3.1 round 2).

View Source
var ErrWrongTxKind = errors.New("zap_native: tx kind discriminator does not match expected tx type")

ErrWrongTxKind is returned by Wrap*Tx when the buffer's TxKind discriminator does not match the expected tx type. Caller passed the wrong buffer to the wrong wrapper — a cross-type confusion attempt or a dispatch bug.

View Source
var ErrZeroExpiry = errors.New(
	"zap_native: RegisterL1ValidatorTx.Expiry must be > 0; zero never represents a legitimate window",
)

ErrZeroExpiry is returned when a RegisterL1ValidatorTx carries Expiry == 0. Wire-layer Expiry is a unix timestamp; zero never represents a legitimate future registration window. Full timestamp-vs-now() gate lives in the executor (R7V7: SyntacticVerify is clock-independent here).

LP-023 Red round 7 R7V7.

View Source
var LegacyEnabled = os.Getenv("LUXD_ENABLE_LEGACY_CODEC") == "1"

LegacyEnabled is true when the operator has set LUXD_ENABLE_LEGACY_CODEC=1.

**Native ZAP is the default.** The codec.Codec{Marshal,Unmarshal} interface is gone from the platformvm hot path. New deployments, fresh syncs, and post-activation production binaries run ZAP-only by default — no legacy code in the read or write path.

Operators MUST set LUXD_ENABLE_LEGACY_CODEC=1 if they need to read pre-activation historical blocks from disk (e.g. validators bootstrapping from a long-history snapshot that includes pre-2026-07-01 P-chain state). Without the flag, legacy-encoded bytes return ErrLegacyCodecDisabled.

Once a validator has synced past the activation height, the flag can be dropped — all subsequent reads are ZAP.

Functions

func IsZAPBytes

func IsZAPBytes(b []byte) bool

IsZAPBytes reports whether the byte buffer is a ZAP-encoded message (recognised by the 4-byte "ZAP\x00" magic). Cheap O(1) check.

Callers use this to discriminate ZAP-encoded txs/blocks from legacy linearcodec-encoded ones during the cross-activation read window (which only happens when LUXD_ENABLE_LEGACY_CODEC=1).

func NewOwnerInline

func NewOwnerInline(b *zap.Builder, in OwnerInput) (threshold uint32, locktime uint64, addrListOff, addrListLen int, err error)

NewOwnerInline writes the Owner's variable-section addresses into the builder and returns the (threshold, locktime, addrListOff, addrListLen) quad ready for the parent ObjectBuilder to write into the embedded Owner header. Returns ErrOwnerSingleAddrUseStub when len(Addresses) < 2.

func ShouldUseZAPForWrite

func ShouldUseZAPForWrite(blockTimestamp uint64) bool

ShouldUseZAPForWrite reports whether new outgoing txs/blocks should be encoded as ZAP.

Default behavior — native ZAP always. ZAPActivationUnix is now 0 (always-on), so the timestamp gate is a no-op except when the operator explicitly opts back into legacy via LUXD_ENABLE_LEGACY_CODEC=1, in which case the original forward-date semantics are preserved for the LegacyEnabled path only.

func WriteAddressList

func WriteAddressList(b *zap.Builder, addrs []ids.ShortID) (offset, entryCount int)

WriteAddressList writes an address list at the builder's current position and returns (offset, entryCount) suitable for ObjectBuilder.SetList.

func WriteChainsList

func WriteChainsList(b *zap.Builder, entries []ChainsListEntry) (
	listOffset, listCount int,
	nameBlobs []byte,
	fxIDsBlobs []byte,
	genesisDataBlobs []byte,
)

WriteChainsList writes a chains list and emits its fixed-stride entries + the three concatenated sibling blob arrays. Callers MUST emit the blob arrays via builder.SetBytes at the parent tx's NameBlobs, FxIDsBlobs, and GenesisDataBlobs fields so the Bind() at the reader side can reattach them.

Returns:

  • listOffset: offset of the chain-entry list within the builder.
  • listCount: number of chain entries (the wire length field).
  • nameBlobs / fxIDsBlobs / genesisDataBlobs: the three sibling byte arrays the caller must emit.

func WriteCredentialList

func WriteCredentialList(b *zap.Builder, entries []CredentialListEntry) (
	credentialListOffset, credentialListCount int,
	signaturesAll [][SigBlobSize]byte,
)

WriteCredentialList writes a credential list and emits its fixed-stride entries. Each entry's SigsStart points into the SignatureArray returned by the second result; callers MUST write that array via WriteSignatureArray and store its (offset, length) in the parent tx's sibling SignatureArray field.

func WriteEvidenceList

func WriteEvidenceList(b *zap.Builder, entries []EvidenceListEntry) (
	listOffset, listCount int,
	messageBlobs []byte,
	signatureBlobs []byte,
)

WriteEvidenceList writes an evidence list and emits its fixed-stride entries. Each entry's MessageA/B + SignatureA/B Rel/Len pairs point into the MessageBlobs and SignatureBlobs byte arrays returned by the second and third results; callers MUST emit those arrays via WriteByteBlobs and store their (offset, length) in the parent tx's sibling MessageBlobs and SignatureBlobs fields.

func WriteInputList

func WriteInputList(b *zap.Builder, entries []InputListEntry) (
	inputListOffset, inputListCount int,
	sigIndicesAll []uint32,
)

WriteInputList writes an input list and emits its fixed-stride entries. Each entry's SigIndicesStart points into the SigIndices array returned by the second result; callers MUST write that array via WriteSigIndicesArray (see below) and store its (offset, length) in the parent tx's SigIndicesArrayRel/Len fields.

Returns:

  • inputListOffset / inputListCount: pass to ObjectBuilder.SetList
  • sigIndicesAll: the concatenated uint32 array; pass to WriteSigIndicesArray for sibling-list emission

func WriteOutputList

func WriteOutputList(b *zap.Builder, entries []OutputListEntry) (offset, entryCount int)

WriteOutputList allocates a ZAP list at the builder's current position and returns (offset, entryCount) suitable for ObjectBuilder.SetList. The returned length is the ENTRY count (not the byte count); SetList stores this verbatim and List.Object(i, SizeTransferableOutput) uses it for stride-indexed access.

Zero-alloc on the hot path: a stack-sized scratch buffer per entry holds the encoded bytes before AddBytes copies them into the ZAP buffer; no per-entry heap allocation.

func WriteSigIndicesArray

func WriteSigIndicesArray(b *zap.Builder, sigs []uint32) (offset, entryCount int)

WriteSigIndicesArray writes the concatenated uint32 sig-index array as a ZAP list and returns (offset, entryCount) for ObjectBuilder.SetList. Pair with WriteInputList above.

func WriteSignatureArray

func WriteSignatureArray(b *zap.Builder, sigs [][SigBlobSize]byte) (offset, entryCount int)

WriteSignatureArray writes the concatenated SigBlobSize-byte signature array as a ZAP list and returns (offset, entryCount) for ObjectBuilder.SetList. Pair with WriteCredentialList above.

func WriteValidatorsList

func WriteValidatorsList(b *zap.Builder, entries []ValidatorsListEntry) (offset, count int)

WriteValidatorsList writes a fixed-stride list of ValidatorRecord entries at the builder's current position and returns (offset, count) suitable for ObjectBuilder.SetList.

Per record: NodeID 20B + Weight 8B + BLSPubKey 48B + BLSPoP 96B + RegistrationExpiry 8B = 180B. No sibling arrays needed.

func WriteWarpMessage

func WriteWarpMessage(b *zap.Builder, sourceNetwork ids.ID, payload []byte) int

WriteWarpMessage writes a WarpMessage object as a nested sub-object inside the builder's buffer and returns its offset. Callers pass the returned offset to ObjectBuilder.SetObject on the parent's WarpMessage field.

Zero-alloc: the per-message scratch buffer is stack-sized; only the payload byte slice (caller-owned) is consulted by reference.

Types

type AddChainValidatorTx

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

func WrapAddChainValidatorTx

func WrapAddChainValidatorTx(b []byte) (AddChainValidatorTx, error)

func (AddChainValidatorTx) BlockchainID

func (t AddChainValidatorTx) BlockchainID() ids.ID

func (AddChainValidatorTx) Bytes

func (t AddChainValidatorTx) Bytes() []byte

func (AddChainValidatorTx) Chain

func (t AddChainValidatorTx) Chain() ids.ID

func (AddChainValidatorTx) Credentials

func (t AddChainValidatorTx) Credentials() CredentialList

func (AddChainValidatorTx) Ins

func (AddChainValidatorTx) IsZero

func (t AddChainValidatorTx) IsZero() bool

func (AddChainValidatorTx) Memo

func (t AddChainValidatorTx) Memo() []byte

func (AddChainValidatorTx) NetworkID

func (t AddChainValidatorTx) NetworkID() uint32

func (AddChainValidatorTx) NodeID

func (t AddChainValidatorTx) NodeID() ids.NodeID

func (AddChainValidatorTx) Outs

func (AddChainValidatorTx) SigIndicesArray

func (t AddChainValidatorTx) SigIndicesArray() SigIndicesArray

func (AddChainValidatorTx) SignatureArray

func (t AddChainValidatorTx) SignatureArray() SignatureArray

func (AddChainValidatorTx) StakeEnd

func (t AddChainValidatorTx) StakeEnd() uint64

func (AddChainValidatorTx) StakeStart

func (t AddChainValidatorTx) StakeStart() uint64

func (AddChainValidatorTx) StakeWeight

func (t AddChainValidatorTx) StakeWeight() uint64

type AddChainValidatorTxInput

type AddChainValidatorTxInput struct {
	NetworkID    uint32
	BlockchainID ids.ID
	Outs         []OutputListEntry
	Ins          []InputListEntry
	Credentials  []CredentialListEntry
	Memo         []byte
	NodeID       ids.NodeID
	StakeStart   uint64
	StakeEnd     uint64
	StakeWeight  uint64
	Chain        ids.ID
}

type AddDelegatorTx

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

func NewAddDelegatorTx

func NewAddDelegatorTx(in AddDelegatorTxInput) AddDelegatorTx

func WrapAddDelegatorTx

func WrapAddDelegatorTx(b []byte) (AddDelegatorTx, error)

func (AddDelegatorTx) BlockchainID

func (t AddDelegatorTx) BlockchainID() ids.ID

func (AddDelegatorTx) Bytes

func (t AddDelegatorTx) Bytes() []byte

func (AddDelegatorTx) Credentials

func (t AddDelegatorTx) Credentials() CredentialList

func (AddDelegatorTx) DelegationRewardsOwner

func (t AddDelegatorTx) DelegationRewardsOwner() (uint32, uint64, ids.ShortID)

func (AddDelegatorTx) Ins

func (t AddDelegatorTx) Ins() InputList

func (AddDelegatorTx) IsZero

func (t AddDelegatorTx) IsZero() bool

func (AddDelegatorTx) Memo

func (t AddDelegatorTx) Memo() []byte

func (AddDelegatorTx) NetworkID

func (t AddDelegatorTx) NetworkID() uint32

func (AddDelegatorTx) NodeID

func (t AddDelegatorTx) NodeID() ids.NodeID

func (AddDelegatorTx) Outs

func (t AddDelegatorTx) Outs() OutputList

func (AddDelegatorTx) SigIndicesArray

func (t AddDelegatorTx) SigIndicesArray() SigIndicesArray

func (AddDelegatorTx) SignatureArray

func (t AddDelegatorTx) SignatureArray() SignatureArray

func (AddDelegatorTx) StakeEnd

func (t AddDelegatorTx) StakeEnd() uint64

func (AddDelegatorTx) StakeOuts

func (t AddDelegatorTx) StakeOuts() OutputList

func (AddDelegatorTx) StakeStart

func (t AddDelegatorTx) StakeStart() uint64

func (AddDelegatorTx) StakeWeight

func (t AddDelegatorTx) StakeWeight() uint64

func (AddDelegatorTx) Verify

func (t AddDelegatorTx) Verify() error

Verify runs SyntacticVerify on the embedded DelegationRewardsOwner of an AddDelegatorTx.

type AddDelegatorTxInput

type AddDelegatorTxInput struct {
	NetworkID              uint32
	BlockchainID           ids.ID
	Outs                   []OutputListEntry
	Ins                    []InputListEntry
	Credentials            []CredentialListEntry
	Memo                   []byte
	NodeID                 ids.NodeID
	StakeStart             uint64
	StakeEnd               uint64
	StakeWeight            uint64
	StakeOuts              []OutputListEntry
	DelegationRewardsOwner OwnerStub
}

type AddPermissionlessDelegatorTx

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

func WrapAddPermissionlessDelegatorTx

func WrapAddPermissionlessDelegatorTx(b []byte) (AddPermissionlessDelegatorTx, error)

func (AddPermissionlessDelegatorTx) BlockchainID

func (t AddPermissionlessDelegatorTx) BlockchainID() ids.ID

func (AddPermissionlessDelegatorTx) Bytes

func (t AddPermissionlessDelegatorTx) Bytes() []byte

func (AddPermissionlessDelegatorTx) Chain

func (AddPermissionlessDelegatorTx) Credentials

func (AddPermissionlessDelegatorTx) DelegationRewardsOwner

func (t AddPermissionlessDelegatorTx) DelegationRewardsOwner() (uint32, uint64, ids.ShortID)

func (AddPermissionlessDelegatorTx) Ins

func (AddPermissionlessDelegatorTx) IsZero

func (AddPermissionlessDelegatorTx) Memo

func (AddPermissionlessDelegatorTx) NetworkID

func (t AddPermissionlessDelegatorTx) NetworkID() uint32

func (AddPermissionlessDelegatorTx) NodeID

func (AddPermissionlessDelegatorTx) Outs

func (AddPermissionlessDelegatorTx) SigIndicesArray

func (t AddPermissionlessDelegatorTx) SigIndicesArray() SigIndicesArray

func (AddPermissionlessDelegatorTx) SignatureArray

func (t AddPermissionlessDelegatorTx) SignatureArray() SignatureArray

func (AddPermissionlessDelegatorTx) StakeAssetID

func (t AddPermissionlessDelegatorTx) StakeAssetID() ids.ID

func (AddPermissionlessDelegatorTx) StakeEnd

func (t AddPermissionlessDelegatorTx) StakeEnd() uint64

func (AddPermissionlessDelegatorTx) StakeOuts

func (AddPermissionlessDelegatorTx) StakeStart

func (t AddPermissionlessDelegatorTx) StakeStart() uint64

func (AddPermissionlessDelegatorTx) StakeWeight

func (t AddPermissionlessDelegatorTx) StakeWeight() uint64

func (AddPermissionlessDelegatorTx) Verify

Verify runs SyntacticVerify on the embedded DelegationRewardsOwner of an AddPermissionlessDelegatorTx.

type AddPermissionlessDelegatorTxInput

type AddPermissionlessDelegatorTxInput struct {
	NetworkID              uint32
	BlockchainID           ids.ID
	Outs                   []OutputListEntry
	Ins                    []InputListEntry
	Credentials            []CredentialListEntry
	Memo                   []byte
	NodeID                 ids.NodeID
	StakeStart             uint64
	StakeEnd               uint64
	StakeWeight            uint64
	Chain                  ids.ID
	StakeAssetID           ids.ID
	StakeOuts              []OutputListEntry
	DelegationRewardsOwner OwnerStub
}

type AddPermissionlessValidatorTx

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

AddPermissionlessValidatorTx is the zero-copy accessor.

func WrapAddPermissionlessValidatorTx

func WrapAddPermissionlessValidatorTx(b []byte) (AddPermissionlessValidatorTx, error)

func (AddPermissionlessValidatorTx) BLSProofOfPossession

func (t AddPermissionlessValidatorTx) BLSProofOfPossession() [bls.SignatureLen]byte

func (AddPermissionlessValidatorTx) BLSPublicKey

func (AddPermissionlessValidatorTx) BlockchainID

func (t AddPermissionlessValidatorTx) BlockchainID() ids.ID

func (AddPermissionlessValidatorTx) Bytes

func (t AddPermissionlessValidatorTx) Bytes() []byte

func (AddPermissionlessValidatorTx) Credentials

func (AddPermissionlessValidatorTx) DelegationRewardsOwner

func (t AddPermissionlessValidatorTx) DelegationRewardsOwner() (uint32, uint64, ids.ShortID)

DelegationRewardsOwner mirrors ValidationRewardsOwner for the delegation rewards owner stub.

func (AddPermissionlessValidatorTx) DelegationShares

func (t AddPermissionlessValidatorTx) DelegationShares() uint32

DelegationShares returns the delegation-shares percentage in units of reward.PercentDenominator.

func (AddPermissionlessValidatorTx) Ins

func (AddPermissionlessValidatorTx) IsZero

func (AddPermissionlessValidatorTx) Memo

func (AddPermissionlessValidatorTx) NetworkID

func (t AddPermissionlessValidatorTx) NetworkID() uint32

func (AddPermissionlessValidatorTx) NodeID

func (AddPermissionlessValidatorTx) Outs

func (AddPermissionlessValidatorTx) SigIndicesArray

func (t AddPermissionlessValidatorTx) SigIndicesArray() SigIndicesArray

func (AddPermissionlessValidatorTx) SignatureArray

func (t AddPermissionlessValidatorTx) SignatureArray() SignatureArray

func (AddPermissionlessValidatorTx) StakeAmount

func (t AddPermissionlessValidatorTx) StakeAmount() uint64

func (AddPermissionlessValidatorTx) StakeAssetID

func (t AddPermissionlessValidatorTx) StakeAssetID() ids.ID

func (AddPermissionlessValidatorTx) StakeEnd

func (t AddPermissionlessValidatorTx) StakeEnd() uint64

func (AddPermissionlessValidatorTx) StakeStart

func (t AddPermissionlessValidatorTx) StakeStart() uint64

func (AddPermissionlessValidatorTx) StakeWeight

func (t AddPermissionlessValidatorTx) StakeWeight() uint64

func (AddPermissionlessValidatorTx) ValidationRewardsOwner

func (t AddPermissionlessValidatorTx) ValidationRewardsOwner() (uint32, uint64, ids.ShortID)

ValidationRewardsOwner returns the (threshold, locktime, address) tuple for the validation-rewards owner. Single-address stub form (v3).

func (AddPermissionlessValidatorTx) Verify

Verify runs SyntacticVerify on both embedded owners of an AddPermissionlessValidatorTx — the ValidationRewardsOwner AND the DelegationRewardsOwner. Either malformed owner fails the whole tx.

type AddPermissionlessValidatorTxInput

type AddPermissionlessValidatorTxInput struct {
	NetworkID    uint32
	BlockchainID ids.ID
	Outs         []OutputListEntry
	Ins          []InputListEntry
	Credentials  []CredentialListEntry
	Memo         []byte

	NodeID               ids.NodeID
	StakeStart           uint64
	StakeEnd             uint64
	StakeWeight          uint64
	StakeAssetID         ids.ID
	StakeAmount          uint64
	BLSPublicKey         [bls.PublicKeyLen]byte
	BLSProofOfPossession [bls.SignatureLen]byte

	ValidationRewardsOwner OwnerStub
	DelegationRewardsOwner OwnerStub
	DelegationShares       uint32
}

AddPermissionlessValidatorTxInput is the constructor input.

type AddValidatorTx

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

func NewAddValidatorTx

func NewAddValidatorTx(in AddValidatorTxInput) AddValidatorTx

func WrapAddValidatorTx

func WrapAddValidatorTx(b []byte) (AddValidatorTx, error)

func (AddValidatorTx) BlockchainID

func (t AddValidatorTx) BlockchainID() ids.ID

func (AddValidatorTx) Bytes

func (t AddValidatorTx) Bytes() []byte

func (AddValidatorTx) Credentials

func (t AddValidatorTx) Credentials() CredentialList

func (AddValidatorTx) DelegationShares

func (t AddValidatorTx) DelegationShares() uint32

func (AddValidatorTx) Ins

func (t AddValidatorTx) Ins() InputList

func (AddValidatorTx) IsZero

func (t AddValidatorTx) IsZero() bool

func (AddValidatorTx) Memo

func (t AddValidatorTx) Memo() []byte

func (AddValidatorTx) NetworkID

func (t AddValidatorTx) NetworkID() uint32

func (AddValidatorTx) NodeID

func (t AddValidatorTx) NodeID() ids.NodeID

func (AddValidatorTx) Outs

func (t AddValidatorTx) Outs() OutputList

func (AddValidatorTx) RewardsOwner

func (t AddValidatorTx) RewardsOwner() (uint32, uint64, ids.ShortID)

func (AddValidatorTx) SigIndicesArray

func (t AddValidatorTx) SigIndicesArray() SigIndicesArray

func (AddValidatorTx) SignatureArray

func (t AddValidatorTx) SignatureArray() SignatureArray

func (AddValidatorTx) StakeEnd

func (t AddValidatorTx) StakeEnd() uint64

func (AddValidatorTx) StakeOuts

func (t AddValidatorTx) StakeOuts() OutputList

func (AddValidatorTx) StakeStart

func (t AddValidatorTx) StakeStart() uint64

func (AddValidatorTx) StakeWeight

func (t AddValidatorTx) StakeWeight() uint64

func (AddValidatorTx) Verify

func (t AddValidatorTx) Verify() error

Verify runs SyntacticVerify on the embedded RewardsOwner of an AddValidatorTx. Wraps the typed error with the tx kind for context.

type AddValidatorTxInput

type AddValidatorTxInput struct {
	NetworkID        uint32
	BlockchainID     ids.ID
	Outs             []OutputListEntry
	Ins              []InputListEntry
	Credentials      []CredentialListEntry
	Memo             []byte
	NodeID           ids.NodeID
	StakeStart       uint64
	StakeEnd         uint64
	StakeWeight      uint64
	StakeOuts        []OutputListEntry
	RewardsOwner     OwnerStub
	DelegationShares uint32
}

type AddressList

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

AddressList is a variable-length list of 20-byte ids.ShortID addresses. Stride is ids.ShortIDLen (20). The wire layer guarantees length*stride fits in the message buffer via Object.ListStride (zap v0.7.2+).

CONSUMER SAFETY (LP-023 Red round 4 R4V3): a malicious wire-encoded AddressList may report Len() > N for an actual N entries via the permissive ListStride clamp (Len() reflects the wire length field only). At(i) for i >= N returns zero-valued ShortID{} — which a naive "iterate every Len() index and treat every ShortID as a valid signer" loop would silently accept as a zero-co-signer. That zero co-signer can match any zero key in a buggy keystore, granting unauthorized spend authority.

Consumers MUST:

  1. Validate each returned address is non-zero before treating it as a signer, OR
  2. Correlate Len() against an explicit count from a sibling field (e.g. parent tx's signer-count uint32), OR
  3. Call Owner.SyntacticVerify() before iterating — it caps the threshold against Len() and rejects empty lists, which closes the "honest overcount" attack at the gate.

Path (3) is the canonical one; the executor-side tx.Verify() entry point invokes Owner.SyntacticVerify().

func AddressListView

func AddressListView(parent zap.Object, fieldOffset int) AddressList

AddressListView reads an AddressList from a parent object's field offset. Uses the per-stride clamp introduced in zap v0.7.2: a poisoned length field that passes the permissive baseline gets rejected here.

READ-ONLY: each address aliases the underlying ZAP buffer.

func (AddressList) At

func (a AddressList) At(i int) ids.ShortID

At returns the i'th address. Returns the zero ShortID when out of range.

CONSUMER SAFETY (R4V3): when i >= the actual entry count (a malicious encoder published a length-padded list), this returns ShortID{} which is the zero address. Treating a zero address as a valid signer in a quorum count is a silent auth bypass. Always validate non-zero before indexing into a keystore, OR use Owner.SyntacticVerify() at the boundary (canonical path) — that gate clamps the threshold against Len() and rejects empty lists, so a malicious overcount can never lead to a "zero co-signer" being accepted.

func (AddressList) IsNull

func (a AddressList) IsNull() bool

IsNull returns true if no list pointer was set.

func (AddressList) Len

func (a AddressList) Len() int

Len returns the number of addresses as reported by the wire-encoded length field. CONSUMER SAFETY: see AddressList type-level docstring — this value is attacker-controlled within the per-stride clamp.

type AdvanceTimeTx

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

AdvanceTimeTx is a zero-copy typed accessor over a ZAP buffer.

func NewAdvanceTimeTx

func NewAdvanceTimeTx(time uint64) AdvanceTimeTx

NewAdvanceTimeTx builds an AdvanceTimeTx into a fresh ZAP buffer.

No reflection. No serialize tag walk. The builder writes TxKind at offset 0 and Time at offset 1 in the object payload, finalizes the ZAP message, and returns a typed accessor over the resulting buffer.

func WrapAdvanceTimeTx

func WrapAdvanceTimeTx(b []byte) (AdvanceTimeTx, error)

WrapAdvanceTimeTx parses a ZAP buffer into a typed accessor.

Zero copy: the returned accessor references the input buffer directly. The caller MUST keep the buffer alive while the accessor is in use. Returns ErrWrongTxKind if the discriminator byte does not match TxKindAdvanceTime; returns ErrInvalidMagic/ErrInvalidVersion from the ZAP layer on a malformed buffer.

func (AdvanceTimeTx) Bytes

func (t AdvanceTimeTx) Bytes() []byte

Bytes returns the underlying ZAP buffer literally. NO encoding step.

func (AdvanceTimeTx) IsZero

func (t AdvanceTimeTx) IsZero() bool

IsZero reports whether the accessor is uninitialized.

func (AdvanceTimeTx) Time

func (t AdvanceTimeTx) Time() uint64

Time returns the timestamp the proposer is suggesting the network advance to. Zero copy, zero allocation.

type BaseTx

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

BaseTx is a zero-copy typed accessor over a ZAP buffer carrying a v3 BaseTx.

func NewBaseTx

func NewBaseTx(networkID uint32, blockchainID ids.ID, memo []byte) BaseTx

NewBaseTx builds a v3 BaseTx into a fresh ZAP buffer. Memo may be nil.

func WrapBaseTx

func WrapBaseTx(b []byte) (BaseTx, error)

WrapBaseTx parses a ZAP buffer into a typed BaseTx accessor.

Returns ErrWrongTxKind if the discriminator byte does not match TxKindBase; returns ErrInvalidMagic/ErrInvalidVersion from the ZAP layer on a malformed buffer.

func (BaseTx) BlockchainID

func (t BaseTx) BlockchainID() ids.ID

BlockchainID returns the chain ID the tx executes against.

func (BaseTx) Bytes

func (t BaseTx) Bytes() []byte

func (BaseTx) IsZero

func (t BaseTx) IsZero() bool

func (BaseTx) Memo

func (t BaseTx) Memo() []byte

Memo returns the memo bytes.

READ-ONLY: the returned slice aliases the underlying ZAP buffer. Mutation corrupts the parsed tx and any TxID = hash(buffer) computed downstream. To own the bytes, copy first: append([]byte(nil), m...).

Zero-copy / zero-allocation contract: a defensive copy would allocate on every call, defeating the native-ZAP design. The read-only discipline is type-system-erased; enforce via review and the lint rule deferred to a follow-up.

func (BaseTx) NetworkID

func (t BaseTx) NetworkID() uint32

NetworkID returns the network ID the tx targets.

type BaseTxFull

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

BaseTxFull is a zero-copy typed accessor over a ZAP buffer carrying a v3 full P-chain spending tx.

func NewBaseTxFull

func NewBaseTxFull(in BaseTxFullInput) BaseTxFull

NewBaseTxFull builds a v3 BaseTxFull into a fresh ZAP buffer. Outs/Ins/ Credentials may each be empty (the corresponding list pointer is (0, 0)).

func WrapBaseTxFull

func WrapBaseTxFull(b []byte) (BaseTxFull, error)

WrapBaseTxFull parses a ZAP buffer into a typed BaseTxFull accessor.

Returns ErrWrongTxKind if the discriminator does not match TxKindBaseFull.

func (BaseTxFull) BlockchainID

func (t BaseTxFull) BlockchainID() ids.ID

BlockchainID returns the chain ID the tx executes against.

func (BaseTxFull) Bytes

func (t BaseTxFull) Bytes() []byte

func (BaseTxFull) Credentials

func (t BaseTxFull) Credentials() CredentialList

Credentials returns the CredentialList view.

func (BaseTxFull) Ins

func (t BaseTxFull) Ins() InputList

Ins returns the InputList view.

func (BaseTxFull) IsZero

func (t BaseTxFull) IsZero() bool

func (BaseTxFull) Memo

func (t BaseTxFull) Memo() []byte

Memo returns the memo bytes.

READ-ONLY: aliases the underlying ZAP buffer. Mutation corrupts the parsed tx and breaks TxID = hash(buffer). Use append([]byte(nil), m...) to take ownership.

func (BaseTxFull) NetworkID

func (t BaseTxFull) NetworkID() uint32

NetworkID returns the network ID the tx targets.

func (BaseTxFull) Outs

func (t BaseTxFull) Outs() OutputList

Outs returns the OutputList view.

func (BaseTxFull) SigIndicesArray

func (t BaseTxFull) SigIndicesArray() SigIndicesArray

SigIndicesArray returns the shared uint32 sig-index array view that the InputList entries slice into.

func (BaseTxFull) SignatureArray

func (t BaseTxFull) SignatureArray() SignatureArray

SignatureArray returns the shared signature blob array view that the CredentialList entries slice into.

type BaseTxFullInput

type BaseTxFullInput struct {
	NetworkID    uint32
	BlockchainID ids.ID
	Outs         []OutputListEntry
	Ins          []InputListEntry
	Credentials  []CredentialListEntry
	Memo         []byte
}

BaseTxFullInput is the constructor input for NewBaseTxFull. The lists are converted to ZAP wire form inside the builder; no separate writer call needed by the caller.

type BoundChainEntry

type BoundChainEntry struct {
	ChainEntry
	// contains filtered or unexported fields
}

BoundChainEntry composes ChainEntry with bound parent blobs. Only this type exposes safe Name/FxIDs/GenesisData accessors.

func (BoundChainEntry) FxIDs

func (e BoundChainEntry) FxIDs() []ids.ID

FxIDs returns the chain's FxID list as a slice of ids.ID. Each FxID is 32 bytes; the entry count = Len / FxIDSize. Returns nil when the cursor falls outside or Len is not a multiple of FxIDSize.

func (BoundChainEntry) GenesisData

func (e BoundChainEntry) GenesisData() []byte

GenesisData returns the chain's genesis blob, clamped against the bound parent GenesisDataBlobs.

func (BoundChainEntry) Name

func (e BoundChainEntry) Name() []byte

Name returns the chain's name bytes, clamped against the bound parent NameBlobs. Returns empty when the wire (Rel, Len) cursors fall outside the parent blob.

type BoundChainsList

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

BoundChainsList is the safe-accessor view over a ChainsListView after Bind(). The bound parent blobs are pinned at the type level so BoundChainsList.At() returns entries whose Name/FxIDs/GenesisData safely slice the blobs.

func (BoundChainsList) At

At returns the i'th BoundChainEntry. The bound parent blobs travel with the entry so Name/FxIDs/GenesisData safely clamp.

func (BoundChainsList) IsNull

func (l BoundChainsList) IsNull() bool

IsNull returns true if no list pointer was set.

func (BoundChainsList) Len

func (l BoundChainsList) Len() int

Len returns the chain count.

type BoundEvidenceEntry

type BoundEvidenceEntry struct {
	EvidenceEntry
	// contains filtered or unexported fields
}

BoundEvidenceEntry composes EvidenceEntry with bound parent blobs. Only this type exposes the safe MessageA/B + SignatureA/B accessors — EvidenceEntry (raw, unbound) does not. NEW-V2 compile-time enforcement.

func (BoundEvidenceEntry) MessageA

func (e BoundEvidenceEntry) MessageA() []byte

MessageA returns the first conflicting message bytes, clamped against the bound parent MessageBlobs. Returns an empty slice when the wire (Rel,Len) cursors fall outside the parent blob.

func (BoundEvidenceEntry) MessageB

func (e BoundEvidenceEntry) MessageB() []byte

MessageB returns the second conflicting message bytes, clamped against the bound parent MessageBlobs.

func (BoundEvidenceEntry) SignatureA

func (e BoundEvidenceEntry) SignatureA() []byte

SignatureA returns the first signature bytes, clamped against the bound parent SignatureBlobs.

func (BoundEvidenceEntry) SignatureB

func (e BoundEvidenceEntry) SignatureB() []byte

SignatureB returns the second signature bytes, clamped against the bound parent SignatureBlobs.

type BoundEvidenceList

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

BoundEvidenceList is the safe-accessor view over an EvidenceListView after Bind(). The bound parent MessageBlobs + SignatureBlobs are pinned at the type level so that BoundEvidenceList.At() returns entries whose MessageA/B + SignatureA/B safely slice the blobs (returning empty on poisoned cursors). Compile-time enforcement: EvidenceListView lacks the safe accessors so consumers cannot bypass Bind() by accident.

func (BoundEvidenceList) At

At returns the i'th BoundEvidenceEntry. The bound parent blobs travel with the entry so MessageA/B and SignatureA/B safely clamp against the blobs returned by the parent tx.

func (BoundEvidenceList) IsNull

func (l BoundEvidenceList) IsNull() bool

IsNull returns true if no list pointer was set.

func (BoundEvidenceList) Len

func (l BoundEvidenceList) Len() int

Len returns the entry count.

type ChainEntry

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

ChainEntry is the zero-copy WIRE view over one entry in a ChainsListView. Like EvidenceEntry, it exposes raw cursor accessors only — the safe Name/FxIDs/GenesisData accessors live on BoundChainEntry, reachable only via ChainsListView.Bind(...). Compile-time enforcement of the "Bind-before-use" contract.

ZERO-VALUE SAFETY: `ChainEntry{}` (returned by ChainsListView.At() on out-of-range / clamped lists) is detectable via IsNull(); calling any accessor on a zero-value entry returns the zero value (VMID=0, (0,0) cursors) instead of panicking. The IsNull guard is the defense-in-depth layer that pairs with the defensive At(i).

func (ChainEntry) FxIDsRange

func (e ChainEntry) FxIDsRange() (uint32, uint32)

FxIDsRange returns the raw (relativeOffset, length-in-bytes) cursors into the parent tx's FxIDsBlobs array. Entry count = Len / FxIDSize.

UNSAFE — call FxIDs() on BoundChainEntry instead. Returns (0,0) on a zero-value entry.

func (ChainEntry) GenesisDataRange

func (e ChainEntry) GenesisDataRange() (uint32, uint32)

GenesisDataRange returns the raw (relativeOffset, length) cursors into the parent tx's GenesisDataBlobs array.

UNSAFE — call GenesisData() on BoundChainEntry instead. Returns (0,0) on a zero-value entry.

func (ChainEntry) IsNull

func (e ChainEntry) IsNull() bool

IsNull returns true if the entry is the zero value (out-of-range At(i) result, or empty list). Accessors on a zero-value entry return zero rather than panic — callers may still want to short-circuit downstream work on IsNull entries.

func (ChainEntry) NameRange

func (e ChainEntry) NameRange() (uint32, uint32)

NameRange returns the raw (relativeOffset, length) wire cursors into the parent tx's NameBlobs array for this chain's name.

UNSAFE — call Name() on BoundChainEntry instead. The raw (Rel, Len) pair carries no clamp; consumers indexing nb[rel:rel+len] panic if an adversary sets len=0xFFFFFFFF or rel > len(nb). Same surface as EvidenceEntry.MessageARange (RED-HIGH-3).

Returns (0,0) on a zero-value entry.

func (ChainEntry) VMID

func (e ChainEntry) VMID() ids.ID

VMID returns the chain's VM identifier. This is fixed-size and safe to read without binding. Returns zero-value on a zero entry.

type ChainsListEntry

type ChainsListEntry struct {
	Name        []byte
	VMID        ids.ID
	FxIDs       []ids.ID
	GenesisData []byte
}

ChainsListEntry is the constructor input for a ChainsList. The variable fields (Name, FxIDs, GenesisData) are concatenated into the shared blob arrays during write; entry header cursors point into them.

type ChainsListView

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

ChainsListView is the zero-copy WIRE view over a list of ChainEntry items. UNBOUND — raw cursor accessors work; safe Name/FxIDs/GenesisData accessors require .Bind(nameBlobs, fxIDsBlobs, genesisDataBlobs).

Compile-time enforcement: ChainsListView lacks the safe accessors so consumers cannot bypass Bind() by accident.

CROSS-BLOB ALIASING ALLOWANCE (LP-023 Red round 6 R6-2 design decision):

A wire-encoded ChainsList may legitimately encode overlapping `(rel, len)` ranges across entries pointing into the shared NameBlobs / FxIDsBlobs / GenesisDataBlobs sibling arrays. For example, two chains with the same VMID may share the same FxIDsBlob range; two chains that share a name template can share the same NameBlob range. The writer (WriteChainsList) concatenates without dedup, so today this is a "won't happen by accident" path — but the WIRE layer must not reject it, because a future writer optimization may emit aliased ranges to shrink the blob arrays.

CONTRACT (the wire layer makes these promises; consumers must respect them):

  1. Name(), FxIDs(), GenesisData() return PAYLOAD slices into the shared blob, NOT identity. Two distinct entries whose `(rel, len)` windows overlap will return byte-equal (or byte-overlapping) slices.

  2. Chain IDENTITY is the (VMID, BlockchainID) pair set by the executor via CreateChainTx. Wire-layer Name is descriptive metadata, not consensus-binding. The executor never derives identity from Name() bytes.

  3. Consumers MUST NOT use returned bytes as a deduplication key. Two entries returning the same Name() bytes are two distinct chains on the network if their (VMID, BlockchainID) differ. Using Name() as a set membership key would silently merge them.

  4. Returned slices are READ-ONLY. Mutating any byte returned from Name() / FxIDs() / GenesisData() corrupts the parent message AND any aliased entries simultaneously. The slice headers point into the wire buffer; there is no copy boundary.

If a future feature requires per-entry NON-overlapping ranges (e.g. to enable in-place mutation of one chain's name without affecting others), add a `ChainsListView.VerifyNonOverlappingRanges() error` method and call it from the relevant tx's Verify() entry. Until then, aliasing is allowed and exercised by the TestChainsList_AllowsOverlappingRanges_DocumentedContract test which pins the byte-equality guarantee.

func NewChainsListView

func NewChainsListView(parent zap.Object, fieldOffset int) ChainsListView

NewChainsListView reads a ChainsListView from a parent object's field offset. Uses the per-stride clamp introduced in zap v0.7.2: a poisoned length field that passes the permissive baseline gets rejected here (R4V9, LP-023 Red round 4).

CONTRACT: callers MUST call .Bind(nameBlobs, fxIDsBlobs, genesisDataBlobs) before using Name/FxIDs/GenesisData accessors. Unbound use returns silent-empty slices — a fail-closed default that masks chains. The BoundChainsList type enforces this at compile-time.

func (ChainsListView) At

func (l ChainsListView) At(i int) ChainEntry

At returns the i'th ChainEntry in raw (unbound) form. Returns zero-value ChainEntry when out of range (defensive: a clamped ListStride view may have Len()=0 after R4V9 rejected a poisoned wire length).

func (ChainsListView) Bind

func (l ChainsListView) Bind(nameBlobs, fxIDsBlobs, genesisDataBlobs []byte) BoundChainsList

Bind attaches the parent tx's NameBlobs, FxIDsBlobs, and GenesisDataBlobs and returns a BoundChainsList whose At() exposes safe Name/FxIDs/GenesisData accessors. The raw (Rel, Len) cursors are attacker-controlled, but the safe accessors clamp against the bound parent blobs.

func (ChainsListView) IsNull

func (l ChainsListView) IsNull() bool

IsNull returns true if no list pointer was set.

func (ChainsListView) Len

func (l ChainsListView) Len() int

Len returns the chain count.

func (ChainsListView) MustVerify added in v1.28.20

func (l ChainsListView) MustVerify() error

MustVerify walks every entry in the list and asserts:

  • FxIDsLen is an exact multiple of FxIDSize (R6V5).
  • RESERVED bytes at offsets [56..64) within each entry are all zero (R6-4 / batch 5 v3.5). The writer pads them to zero; a parser that ignores them lets an adversary smuggle non-zero state inside what consensus considers an empty region. Today that's invisible; the day a v4 parser attaches meaning to byte 56 (e.g. a subnet flag), every v3 tx with non-zero reserved bytes silently means two different things on v3 vs v4 nodes — a wire-fork. Reject NOW.

The check is pure cursor inspection — no Bind required, no blob slicing. Wired into CreateSovereignL1Tx.Verify (and any future tx that embeds a ChainsList).

Returns the first failure wrapped with the entry index. Returns nil when the list is empty or every entry passes — empty-list rejection is the caller's gate (CreateSovereignL1Tx.Verify enforces non-empty via ErrZeroChains before invoking this).

LP-023 Red round 7 R7V8 renamed Verify → MustVerify. The receiver- name pattern makes "I forgot to call this" a grep-able regression: the audit gate (audit_test.go + .github/workflows/zap-audit.yml chainslist-verify-gate) walks every file that embeds a ChainsList in a tx type and confirms it calls .MustVerify() somewhere inside its Verify() body. The previous Verify() name collided with the tx-level Verify() convention and invited the reader to assume "the tx Verify already covered this" — wrong, because the tx-level Verify is responsible for orchestrating the per-field gates, not the list-level walk.

type ConvertNetworkToL1Tx

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

func WrapConvertNetworkToL1Tx

func WrapConvertNetworkToL1Tx(b []byte) (ConvertNetworkToL1Tx, error)

func (ConvertNetworkToL1Tx) Address

func (t ConvertNetworkToL1Tx) Address() []byte

Address returns the L1 manager contract address bytes. READ-ONLY: aliases the underlying ZAP buffer (see BaseTxFull.Memo for the contract).

func (ConvertNetworkToL1Tx) BlockchainID

func (t ConvertNetworkToL1Tx) BlockchainID() ids.ID

func (ConvertNetworkToL1Tx) Bytes

func (t ConvertNetworkToL1Tx) Bytes() []byte

func (ConvertNetworkToL1Tx) Chain

func (t ConvertNetworkToL1Tx) Chain() ids.ID

func (ConvertNetworkToL1Tx) Credentials

func (t ConvertNetworkToL1Tx) Credentials() CredentialList

func (ConvertNetworkToL1Tx) Ins

func (ConvertNetworkToL1Tx) IsZero

func (t ConvertNetworkToL1Tx) IsZero() bool

func (ConvertNetworkToL1Tx) ManagerChainID

func (t ConvertNetworkToL1Tx) ManagerChainID() ids.ID

func (ConvertNetworkToL1Tx) Memo

func (t ConvertNetworkToL1Tx) Memo() []byte

func (ConvertNetworkToL1Tx) NetworkID

func (t ConvertNetworkToL1Tx) NetworkID() uint32

func (ConvertNetworkToL1Tx) Outs

func (ConvertNetworkToL1Tx) SigIndicesArray

func (t ConvertNetworkToL1Tx) SigIndicesArray() SigIndicesArray

func (ConvertNetworkToL1Tx) SignatureArray

func (t ConvertNetworkToL1Tx) SignatureArray() SignatureArray

func (ConvertNetworkToL1Tx) Validators

func (t ConvertNetworkToL1Tx) Validators() ValidatorsList

Validators returns the initial-validator set as a fixed-stride list view over ValidatorRecord entries (180B per record). Uses Object.ListStride for per-element clamp against poisoned wire length fields.

func (ConvertNetworkToL1Tx) Verify added in v1.28.20

func (t ConvertNetworkToL1Tx) Verify() error

Verify pins R7V7 HIGH for ConvertNetworkToL1Tx: the Validators sub-list must be non-empty, every validator's Weight must be > 0, and every validator's BLS proof-of-possession must verify. Same per-validator walk as CreateSovereignL1Tx — the two tx types share the ValidatorsList primitive, and any malformed entry in either is a quorum-skew or authority-substitution primitive.

LP-023 Red round 7 R7V7 closes the gap where ConvertNetworkToL1Tx was excluded from Blue's 8-tx Verify() list. Defense-in-depth pairing with the mempool admission gate (R7V5).

Note: the legacy txs.ConvertNetworkToL1Tx executor is already implemented (standard_tx_executor.go:639), but the zap_native wire path still needs the syntactic gate so when zap_native ConvertNetworkToL1 finally wires into the codec, the executor admission boundary is covered defense-in-depth alongside the network-layer R7V5 gate.

type ConvertNetworkToL1TxInput

type ConvertNetworkToL1TxInput struct {
	NetworkID      uint32
	BlockchainID   ids.ID
	Outs           []OutputListEntry
	Ins            []InputListEntry
	Credentials    []CredentialListEntry
	Memo           []byte
	Chain          ids.ID
	ManagerChainID ids.ID
	Address        []byte
	Validators     []ValidatorsListEntry
}

type CreateChainTx

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

CreateChainTx is the zero-copy accessor.

func NewCreateChainTx

func NewCreateChainTx(in CreateChainTxInput) CreateChainTx

func WrapCreateChainTx

func WrapCreateChainTx(b []byte) (CreateChainTx, error)

func (CreateChainTx) BlockchainID

func (t CreateChainTx) BlockchainID() ids.ID

func (CreateChainTx) Bytes

func (t CreateChainTx) Bytes() []byte

func (CreateChainTx) Credentials

func (t CreateChainTx) Credentials() CredentialList

func (CreateChainTx) GenesisData

func (t CreateChainTx) GenesisData() []byte

GenesisData returns the chain's genesis bytes.

READ-ONLY: see BaseTxFull.Memo for the aliasing contract.

func (CreateChainTx) Ins

func (t CreateChainTx) Ins() InputList

func (CreateChainTx) IsZero

func (t CreateChainTx) IsZero() bool

func (CreateChainTx) Memo

func (t CreateChainTx) Memo() []byte

func (CreateChainTx) NetworkID

func (t CreateChainTx) NetworkID() uint32

func (CreateChainTx) Outs

func (t CreateChainTx) Outs() OutputList

func (CreateChainTx) Owner

func (t CreateChainTx) Owner() (uint32, uint64, ids.ShortID)

func (CreateChainTx) ParentNetwork

func (t CreateChainTx) ParentNetwork() ids.ID

func (CreateChainTx) SigIndicesArray

func (t CreateChainTx) SigIndicesArray() SigIndicesArray

func (CreateChainTx) SignatureArray

func (t CreateChainTx) SignatureArray() SignatureArray

func (CreateChainTx) VMID

func (t CreateChainTx) VMID() ids.ID

func (CreateChainTx) Verify

func (t CreateChainTx) Verify() error

Verify runs SyntacticVerify on the embedded Owner of a CreateChainTx.

func (CreateChainTx) WarpMessageHash

func (t CreateChainTx) WarpMessageHash() ids.ID

WarpMessageHash returns the SHA-256 hash of the originating Warp message. Returns the zero ids.ID when this CreateChain was not originated via a cross-network commit.

type CreateChainTxInput

type CreateChainTxInput struct {
	NetworkID       uint32
	BlockchainID    ids.ID
	Outs            []OutputListEntry
	Ins             []InputListEntry
	Credentials     []CredentialListEntry
	Memo            []byte
	ParentNetwork   ids.ID
	VMID            ids.ID
	Owner           OwnerStub
	WarpMessageHash ids.ID
	GenesisData     []byte
}

CreateChainTxInput is the constructor input.

type CreateNetworkTx

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

func NewCreateNetworkTx

func NewCreateNetworkTx(in CreateNetworkTxInput) CreateNetworkTx

func WrapCreateNetworkTx

func WrapCreateNetworkTx(b []byte) (CreateNetworkTx, error)

func (CreateNetworkTx) BlockchainID

func (t CreateNetworkTx) BlockchainID() ids.ID

func (CreateNetworkTx) Bytes

func (t CreateNetworkTx) Bytes() []byte

func (CreateNetworkTx) Credentials

func (t CreateNetworkTx) Credentials() CredentialList

func (CreateNetworkTx) Ins

func (t CreateNetworkTx) Ins() InputList

func (CreateNetworkTx) IsZero

func (t CreateNetworkTx) IsZero() bool

func (CreateNetworkTx) Memo

func (t CreateNetworkTx) Memo() []byte

func (CreateNetworkTx) NetworkID

func (t CreateNetworkTx) NetworkID() uint32

func (CreateNetworkTx) Outs

func (t CreateNetworkTx) Outs() OutputList

func (CreateNetworkTx) Owner

func (t CreateNetworkTx) Owner() (uint32, uint64, ids.ShortID)

func (CreateNetworkTx) SigIndicesArray

func (t CreateNetworkTx) SigIndicesArray() SigIndicesArray

func (CreateNetworkTx) SignatureArray

func (t CreateNetworkTx) SignatureArray() SignatureArray

func (CreateNetworkTx) Verify

func (t CreateNetworkTx) Verify() error

Verify runs SyntacticVerify on the embedded Owner of a CreateNetworkTx.

type CreateNetworkTxInput

type CreateNetworkTxInput struct {
	NetworkID    uint32
	BlockchainID ids.ID
	Outs         []OutputListEntry
	Ins          []InputListEntry
	Credentials  []CredentialListEntry
	Memo         []byte
	Owner        OwnerStub
}

type CreateSovereignL1Tx

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

func WrapCreateSovereignL1Tx

func WrapCreateSovereignL1Tx(b []byte) (CreateSovereignL1Tx, error)

func (CreateSovereignL1Tx) BlockchainID

func (t CreateSovereignL1Tx) BlockchainID() ids.ID

func (CreateSovereignL1Tx) BoundChains

func (t CreateSovereignL1Tx) BoundChains() BoundChainsList

BoundChains is the convenience accessor that auto-binds the three sibling blobs and returns the safe-accessor BoundChainsList. Prefer this in consumer code; the explicit Chains()+Bind() path is reserved for tests and lower-level wire inspection.

func (CreateSovereignL1Tx) Bytes

func (t CreateSovereignL1Tx) Bytes() []byte

func (CreateSovereignL1Tx) Chains

Chains returns the chains-to-create list as an UNBOUND ChainsListView. Callers MUST invoke .Bind(NameBlobs(), FxIDsBlobs(), GenesisDataBlobs()) to get a BoundChainsList with safe Name/FxIDs/GenesisData accessors. Compile-time enforcement of NEW-V2 (see ChainsListView docstring).

func (CreateSovereignL1Tx) Credentials

func (t CreateSovereignL1Tx) Credentials() CredentialList

func (CreateSovereignL1Tx) FxIDsBlobs

func (t CreateSovereignL1Tx) FxIDsBlobs() []byte

FxIDsBlobs returns the concatenated FxIDs sibling array. Entry count per chain = FxIDsLen / FxIDSize.

func (CreateSovereignL1Tx) GenesisDataBlobs

func (t CreateSovereignL1Tx) GenesisDataBlobs() []byte

GenesisDataBlobs returns the concatenated genesis-blob sibling array.

func (CreateSovereignL1Tx) Ins

func (CreateSovereignL1Tx) IsZero

func (t CreateSovereignL1Tx) IsZero() bool

func (CreateSovereignL1Tx) ManagerAddress

func (t CreateSovereignL1Tx) ManagerAddress() []byte

func (CreateSovereignL1Tx) ManagerChainIdx

func (t CreateSovereignL1Tx) ManagerChainIdx() uint32

func (CreateSovereignL1Tx) Memo

func (t CreateSovereignL1Tx) Memo() []byte

func (CreateSovereignL1Tx) NameBlobs

func (t CreateSovereignL1Tx) NameBlobs() []byte

NameBlobs returns the concatenated chain-name bytes sibling array. Each chain's name lives at (NameRel, NameLen) within this blob — but consumers should reach for BoundChains() instead of indexing directly.

func (CreateSovereignL1Tx) NetworkID

func (t CreateSovereignL1Tx) NetworkID() uint32

func (CreateSovereignL1Tx) Outs

func (CreateSovereignL1Tx) Owner

func (CreateSovereignL1Tx) SigIndicesArray

func (t CreateSovereignL1Tx) SigIndicesArray() SigIndicesArray

func (CreateSovereignL1Tx) SignatureArray

func (t CreateSovereignL1Tx) SignatureArray() SignatureArray

func (CreateSovereignL1Tx) Validators

func (t CreateSovereignL1Tx) Validators() ValidatorsList

Validators returns the initial-validator set as a fixed-stride list view over ValidatorRecord entries (180B per record).

func (CreateSovereignL1Tx) Verify

func (t CreateSovereignL1Tx) Verify() error

Verify runs SyntacticVerify on the embedded Owner of a CreateSovereignL1Tx AND enforces R6V4 / R6V3 / R6V5: the initial validator set must be non-empty, every validator must have non-zero weight, every validator's BLS PoP must verify, the chains list must be non-empty, and every chain entry's FxIDsLen must be an exact multiple of FxIDSize.

Notes:

  • Per-validator RegistrationExpiry > now() is intentionally NOT enforced here. SyntacticVerify is clock-independent (executor wall-clock lives in the staking handler), so the expiry check lives there. This file enforces only properties that are invariant under wire encoding.
  • The BLS pairing check is fast enough at the SyntacticVerify boundary for small validator lists (< 100). For large lists the cost is O(n) pairings, still well under the executor budget.

type CreateSovereignL1TxInput

type CreateSovereignL1TxInput struct {
	NetworkID       uint32
	BlockchainID    ids.ID
	Outs            []OutputListEntry
	Ins             []InputListEntry
	Credentials     []CredentialListEntry
	Memo            []byte
	Owner           OwnerStub
	ManagerChainIdx uint32
	ManagerAddress  []byte
	Validators      []ValidatorsListEntry
	Chains          []ChainsListEntry
}

type Credential

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

Credential is the zero-copy view over one entry in a CredentialList.

func (Credential) SigsCount

func (c Credential) SigsCount() uint32

SigsCount returns the number of signatures for this credential.

func (Credential) SigsStart

func (c Credential) SigsStart() uint32

SigsStart returns the start index into the shared signature array.

type CredentialList

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

CredentialList is the zero-copy view over a list of Credentials.

func CredentialListView

func CredentialListView(parent zap.Object, fieldOffset int) CredentialList

CredentialListView reads a CredentialList from a parent object's field offset. Uses the per-stride clamp introduced in zap v0.7.2: a poisoned length field that passes the permissive baseline gets rejected here (R4V9, LP-023 Red round 4).

func (CredentialList) At

func (l CredentialList) At(i int) Credential

At returns the i'th Credential. Returns the zero-value Credential when out of range (defensive: a clamped ListStride view may have Len()=0 after R4V9 rejected a poisoned wire length; constructing a Credential from List.Object{} on that view would carry a nil msg and panic on downstream field reads).

func (CredentialList) IsNull

func (l CredentialList) IsNull() bool

IsNull returns true if no list pointer was set.

func (CredentialList) Len

func (l CredentialList) Len() int

Len returns the credential count.

type CredentialListEntry

type CredentialListEntry struct {
	// Sigs is the per-credential signature slice. Each sig MUST be exactly
	// SigBlobSize (65) bytes. The constructor panics on a length violation
	// since wrong-length sigs are a constructor bug (caller-side) not a
	// wire-format malleability surface.
	Sigs [][SigBlobSize]byte
}

CredentialListEntry is the constructor input for a CredentialList.

type DisableL1ValidatorTx

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

func NewDisableL1ValidatorTx

func NewDisableL1ValidatorTx(validationID ids.ID) DisableL1ValidatorTx

func WrapDisableL1ValidatorTx

func WrapDisableL1ValidatorTx(b []byte) (DisableL1ValidatorTx, error)

func (DisableL1ValidatorTx) Bytes

func (t DisableL1ValidatorTx) Bytes() []byte

func (DisableL1ValidatorTx) IsZero

func (t DisableL1ValidatorTx) IsZero() bool

func (DisableL1ValidatorTx) ValidationID

func (t DisableL1ValidatorTx) ValidationID() ids.ID

type EvidenceEntry

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

EvidenceEntry is the zero-copy WIRE view over one entry in an EvidenceListView. It exposes raw (Rel,Len) cursor accessors only — the safe MessageA/B + SignatureA/B accessors live on BoundEvidenceEntry, reachable only via EvidenceListView.Bind(...).At(i). Compile-time enforcement of NEW-V2 (LP-023 Red round 3).

The raw *Range() accessors below are UNSAFE: they return the wire (Rel,Len) verbatim without clamping. Consumers that index parent blobs directly with these values can be panicked by an adversary who sets Len=0xFFFFFFFF. New code MUST go through BoundEvidenceEntry's safe accessors. The Range() helpers remain for legacy internal constructors (RED-HIGH-3, LP-023 v3.1 round 2).

func (EvidenceEntry) EvidenceType

func (e EvidenceEntry) EvidenceType() uint8

EvidenceType returns the equivocation type (e.g. double-vote, double-sign). Enum interpretation lives in the executor; the wire layer is opaque.

func (EvidenceEntry) Height

func (e EvidenceEntry) Height() uint64

Height returns the height at which the slashable equivocation occurred.

func (EvidenceEntry) MessageARange

func (e EvidenceEntry) MessageARange() (uint32, uint32)

MessageARange returns the raw (start, length) wire cursors into the parent tx's MessageBlobs array for the first conflicting message.

UNSAFE — call MessageA() instead. The raw (Rel,Len) pair carries no clamp; consumers indexing mb[rel:rel+len] panic if an adversary set len=0xFFFFFFFF or rel>len(mb). RED-HIGH-3.

func (EvidenceEntry) MessageBRange

func (e EvidenceEntry) MessageBRange() (uint32, uint32)

MessageBRange returns the raw (start, length) wire cursors for the second conflicting message.

UNSAFE — call MessageB() instead. See MessageARange.

func (EvidenceEntry) SignatureARange

func (e EvidenceEntry) SignatureARange() (uint32, uint32)

SignatureARange returns the raw (start, length) wire cursors for the first signature.

UNSAFE — call SignatureA() instead. See MessageARange.

func (EvidenceEntry) SignatureBRange

func (e EvidenceEntry) SignatureBRange() (uint32, uint32)

SignatureBRange returns the raw (start, length) wire cursors for the second signature.

UNSAFE — call SignatureB() instead. See MessageARange.

type EvidenceListEntry

type EvidenceListEntry struct {
	Height       uint64
	EvidenceType uint8
	MessageA     []byte
	SignatureA   []byte
	MessageB     []byte
	SignatureB   []byte
}

EvidenceListEntry is the constructor input for an EvidenceList. The four byte slices are concatenated into the shared blob arrays during write; entry header indices point into them.

type EvidenceListView

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

EvidenceListView is the zero-copy WIRE view over a list of EvidenceEntry items. The view is UNBOUND — its raw cursor accessors (Range methods on EvidenceEntry) are exposed for legacy internal constructors, but the safe accessors MessageA/B + SignatureA/B are NOT available on the entries returned by EvidenceListView.At().

To get safe accessors, call .Bind(messageBlobs, signatureBlobs) to convert to BoundEvidenceList. This is a compile-time enforcement of NEW-V2 (LP-023 Red round 3 follow-up #1): consumers cannot accidentally read raw (Rel,Len) cursors and panic on attacker-set length=0xFFFFFFFF; the type system forces them through Bind() first.

func NewEvidenceListView

func NewEvidenceListView(parent zap.Object, fieldOffset int) EvidenceListView

NewEvidenceListView reads an EvidenceListView from a parent object's field offset. Uses the per-stride clamp introduced in zap v0.7.2: a poisoned length field that passes the permissive baseline gets rejected here (R4V9, LP-023 Red round 4).

CONTRACT: callers MUST call .Bind(messageBlobs, signatureBlobs) before using MessageA/B/SignatureA/B accessors. Unbound use returns silent-empty slices — a fail-closed default that masks evidence in slashing logic. The BoundEvidenceList type enforces this at compile-time: the unbound EvidenceListView lacks the safe accessors entirely, forcing consumers through Bind() to get a BoundEvidenceList.

func (EvidenceListView) At

At returns the i'th EvidenceEntry in raw (unbound) form. The entry's Range accessors work; the bound-only MessageA/B + SignatureA/B safe accessors are absent. For consumer-side safe access, call .Bind() to produce a BoundEvidenceList and iterate via BoundEvidenceList.At().

Returns the zero-value EvidenceEntry when out of range (defensive: a clamped ListStride view may have Len()=0 after R4V9 rejected a poisoned wire length; constructing an EvidenceEntry from List.Object{} on that view would carry a nil msg and panic on downstream field reads).

func (EvidenceListView) Bind

func (l EvidenceListView) Bind(messageBlobs, signatureBlobs []byte) BoundEvidenceList

Bind attaches the parent tx's MessageBlobs and SignatureBlobs and returns a BoundEvidenceList whose At() exposes safe MessageA/B + SignatureA/B accessors. The raw (Rel,Len) cursors are attacker-controlled, but the safe accessors clamp against the bound parent blobs and return empty slices on poisoned cursors. RED-HIGH-3 + NEW-V2.

func (EvidenceListView) IsNull

func (l EvidenceListView) IsNull() bool

IsNull returns true if no list pointer was set.

func (EvidenceListView) Len

func (l EvidenceListView) Len() int

Len returns the entry count.

type ExportTx

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

ExportTx is the zero-copy accessor for a v3 ExportTx.

func NewExportTx

func NewExportTx(in ExportTxInput) ExportTx

func WrapExportTx

func WrapExportTx(b []byte) (ExportTx, error)

func (ExportTx) BlockchainID

func (t ExportTx) BlockchainID() ids.ID

func (ExportTx) Bytes

func (t ExportTx) Bytes() []byte

func (ExportTx) Credentials

func (t ExportTx) Credentials() CredentialList

func (ExportTx) DestinationNetwork

func (t ExportTx) DestinationNetwork() ids.ID

DestinationNetwork returns the network identifier the exports flow to.

func (ExportTx) ExportedOutsRange

func (t ExportTx) ExportedOutsRange() (uint32, uint32)

ExportedOutsRange returns (start, count) marking the exported-output slice within the Outs list. Outs[0..start) are local change; Outs[start..start+count) are the exported outputs.

func (ExportTx) Ins

func (t ExportTx) Ins() InputList

func (ExportTx) IsZero

func (t ExportTx) IsZero() bool

func (ExportTx) Memo

func (t ExportTx) Memo() []byte

Memo returns the memo bytes. READ-ONLY (see BaseTxFull.Memo).

func (ExportTx) NetworkID

func (t ExportTx) NetworkID() uint32

func (ExportTx) Outs

func (t ExportTx) Outs() OutputList

func (ExportTx) SigIndicesArray

func (t ExportTx) SigIndicesArray() SigIndicesArray

func (ExportTx) SignatureArray

func (t ExportTx) SignatureArray() SignatureArray

type ExportTxInput

type ExportTxInput struct {
	NetworkID          uint32
	BlockchainID       ids.ID
	DestinationNetwork ids.ID
	LocalOuts          []OutputListEntry
	ExportedOuts       []OutputListEntry
	Ins                []InputListEntry
	Credentials        []CredentialListEntry
	Memo               []byte
}

ExportTxInput is the constructor input for NewExportTx.

type ImportTx

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

ImportTx is the zero-copy accessor for an v3 ImportTx.

func NewImportTx

func NewImportTx(in ImportTxInput) ImportTx

func WrapImportTx

func WrapImportTx(b []byte) (ImportTx, error)

func (ImportTx) BlockchainID

func (t ImportTx) BlockchainID() ids.ID

func (ImportTx) Bytes

func (t ImportTx) Bytes() []byte

func (ImportTx) Credentials

func (t ImportTx) Credentials() CredentialList

func (ImportTx) ImportedInsRange

func (t ImportTx) ImportedInsRange() (uint32, uint32)

ImportedInsRange returns (start, count) marking the imported-input slice within the Ins list. Ins[0..start) are local fee-payers; Ins[start..start+count) are the imported (remote-source) inputs.

func (ImportTx) Ins

func (t ImportTx) Ins() InputList

func (ImportTx) IsZero

func (t ImportTx) IsZero() bool

func (ImportTx) Memo

func (t ImportTx) Memo() []byte

Memo returns the memo bytes. READ-ONLY (see BaseTxFull.Memo).

func (ImportTx) NetworkID

func (t ImportTx) NetworkID() uint32

func (ImportTx) Outs

func (t ImportTx) Outs() OutputList

func (ImportTx) SigIndicesArray

func (t ImportTx) SigIndicesArray() SigIndicesArray

func (ImportTx) SignatureArray

func (t ImportTx) SignatureArray() SignatureArray

func (ImportTx) SourceNetwork

func (t ImportTx) SourceNetwork() ids.ID

SourceNetwork returns the network identifier the UTXOs are imported from.

type ImportTxInput

type ImportTxInput struct {
	NetworkID     uint32
	BlockchainID  ids.ID
	SourceNetwork ids.ID
	Outs          []OutputListEntry
	LocalIns      []InputListEntry
	ImportedIns   []InputListEntry
	Credentials   []CredentialListEntry
	Memo          []byte
}

ImportTxInput is the constructor input for NewImportTx. LocalIns and ImportedIns are written as a single combined list; the constructor records ImportedInsStart = len(LocalIns).

type IncreaseL1ValidatorBalanceTx

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

func NewIncreaseL1ValidatorBalanceTx

func NewIncreaseL1ValidatorBalanceTx(validationID ids.ID, balance uint64) IncreaseL1ValidatorBalanceTx

func WrapIncreaseL1ValidatorBalanceTx

func WrapIncreaseL1ValidatorBalanceTx(b []byte) (IncreaseL1ValidatorBalanceTx, error)

func (IncreaseL1ValidatorBalanceTx) Balance

func (IncreaseL1ValidatorBalanceTx) Bytes

func (t IncreaseL1ValidatorBalanceTx) Bytes() []byte

func (IncreaseL1ValidatorBalanceTx) IsZero

func (IncreaseL1ValidatorBalanceTx) ValidationID

func (t IncreaseL1ValidatorBalanceTx) ValidationID() ids.ID

type InputList

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

InputList is the zero-copy view over a list of TransferableInput entries.

func InputListView

func InputListView(parent zap.Object, fieldOffset int) InputList

InputListView reads an InputList from a parent object's field offset. Uses the per-stride clamp introduced in zap v0.7.2: a poisoned length field that passes the permissive baseline gets rejected here (R4V9, LP-023 Red round 4).

func (InputList) At

At returns the i'th TransferableInput. Returns the zero-value TransferableInput when out of range (defensive: a clamped ListStride view may have Len()=0 after R4V9 rejected a poisoned wire length; constructing a TransferableInput from List.Object{} on that view would carry a nil msg and panic on downstream field reads).

func (InputList) IsNull

func (l InputList) IsNull() bool

IsNull returns true if no list pointer was set.

func (InputList) Len

func (l InputList) Len() int

Len returns the entry count.

type InputListEntry

type InputListEntry struct {
	TxID        ids.ID
	OutputIndex uint32
	AssetID     ids.ID
	Amount      uint64
	SigIndices  []uint32
}

InputListEntry is the constructor input for an InputList. SigIndices is the per-input signature-index slice; WriteInputList concatenates them all and returns a shared-array view that constructors store as a sibling field.

type OutputList

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

OutputList is the zero-copy view over a list of TransferableOutput entries.

func OutputListView

func OutputListView(parent zap.Object, fieldOffset int) OutputList

OutputListView reads an OutputList from a parent object's field offset. Uses the per-stride clamp introduced in zap v0.7.2: a poisoned length field that passes the permissive baseline gets rejected here (R4V9, LP-023 Red round 4).

READ-ONLY: each TransferableOutput aliases the underlying ZAP buffer. Mutation corrupts the parsed tx and any TxID = hash(buffer) computed downstream. To own the bytes, copy first: append([]byte(nil), buf...).

func (OutputList) At

At returns the i'th TransferableOutput. Returns the zero-value TransferableOutput when out of range (defensive: a clamped ListStride view may have Len()=0 after R4V9 rejected a poisoned wire length; constructing a TransferableOutput from List.Object{} on that view would carry a nil msg and panic on downstream field reads).

func (OutputList) IsNull

func (l OutputList) IsNull() bool

IsNull returns true if no list pointer was set.

func (OutputList) Len

func (l OutputList) Len() int

Len returns the number of entries.

type OutputListEntry

type OutputListEntry struct {
	AssetID      ids.ID
	Amount       uint64
	Threshold    uint32
	Locktime     uint64
	OwnerAddress ids.ShortID
}

OutputListEntry is the input to an OutputList builder. Constructors copy each field into the list-builder's stride.

type Owner

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

Owner is the zero-copy accessor over an Owner header embedded in a parent tx. The AddressList view spans the parent's variable section.

Owner stores the parent + base offset (not a sub-Object) because zap.Object is opaque to in-place sub-views; we read each field via parent.UintX at the (baseOffset + fieldOffset) position.

func OwnerView

func OwnerView(parent zap.Object, fieldOffset int) Owner

OwnerView reads an Owner from a parent object's embedded-header offset. The Owner header is INLINE within the parent's fixed section (size SizeOwnerHeader = 20 bytes), so this returns a sub-view rather than dereferencing a relative pointer.

Use case: a parent tx struct reserves SizeOwnerHeader bytes at a known offset for the embedded Owner; this constructor returns the accessor.

func (Owner) Addresses

func (o Owner) Addresses() AddressList

Addresses returns the AddressList view. Each address aliases the parent ZAP buffer.

func (Owner) Locktime

func (o Owner) Locktime() uint64

Locktime returns the unix timestamp before which the owner cannot spend.

func (Owner) SyntacticVerify

func (o Owner) SyntacticVerify() error

SyntacticVerify enforces R4V7 + R4V3 executor-side semantic gates on an Owner header parsed from an untrusted wire buffer. Returns one of:

  • nil — Owner is well-formed: threshold ∈ [1, Addresses.Len()], Addresses.Len() > 0, AND every Address is non-zero.
  • ErrOwnerAddrsEmpty — Addresses.Len() == 0 (signer set undefined).
  • ErrOwnerThresholdZero — threshold == 0 (authorization bypass).
  • ErrOwnerThresholdExceedsAddrs — threshold > Addresses.Len() (unsatisfiable quorum).
  • ErrOwnerAddrZero — at least one address is the zero ShortID. This closes R4V3: a malicious wire-encoded list with honest overcount returns zero-padded phantom entries at i >= actual_count, which a naive consumer treats as a "zero co-signer". Fail-closed here.

CONTRACT (LP-023 Red round 4 R4V7 + R4V3): every tx executor's Verify() entry point MUST call SyntacticVerify on every Owner consumed from a wire buffer before treating the Threshold/Addresses pair as a quorum gate. The wire layer (ZAP) is permissive by design — semantic gates live here in the consumer.

Ordering: addrs-empty → threshold-zero → threshold-exceeds → walk for zero-addresses. The walk is O(Len()) but acceptable: typical owners have <= 5 addresses; the verify is the only authorization gate.

func (Owner) Threshold

func (o Owner) Threshold() uint32

Threshold returns the signature-required count.

type OwnerInput

type OwnerInput struct {
	Threshold uint32
	Locktime  uint64
	Addresses []ids.ShortID
}

OwnerInput is the constructor input for a multi-address Owner.

type OwnerStub

type OwnerStub struct {
	Threshold uint32
	Locktime  uint64
	Address   ids.ShortID
}

OwnerStub is the v3 single-address owner stub used by APV's two rewards-owner fields.

func (OwnerStub) SyntacticVerify

func (s OwnerStub) SyntacticVerify() error

SyntacticVerify enforces R4V7 executor-side semantic gates on an OwnerStub. The stub by construction carries exactly ONE address, so the only valid threshold value is 1. Returns:

  • nil — Threshold == 1 and Address != zero-ShortID.
  • ErrOwnerThresholdZero — Threshold == 0 (auth bypass).
  • ErrOwnerThresholdExceedsAddrs — Threshold > 1 (unsatisfiable: only one address present, no quorum > 1 can ever be reached).

The address-zero check is intentionally NOT enforced here: a zero ShortID is not a wire-protocol violation, only a usability footgun (no key can ever match), so the executor catches it at the spend stage if the user fat-fingers it.

CONTRACT (parallel of Owner.SyntacticVerify): every tx executor's Verify() entry point that consumes an OwnerStub from a wire buffer MUST call SyntacticVerify before treating Threshold as a quorum gate.

type RegisterL1ValidatorTx

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

func NewRegisterL1ValidatorTx

func NewRegisterL1ValidatorTx(
	validationID ids.ID,
	blsPublicKey [bls.PublicKeyLen]byte,
	proofOfPossession [bls.SignatureLen]byte,
	expiry uint64,
	remainingBalanceOwnerID ids.ID,
) RegisterL1ValidatorTx

func WrapRegisterL1ValidatorTx

func WrapRegisterL1ValidatorTx(b []byte) (RegisterL1ValidatorTx, error)

func (RegisterL1ValidatorTx) BLSPublicKey

func (t RegisterL1ValidatorTx) BLSPublicKey() [bls.PublicKeyLen]byte

BLSPublicKey returns the compressed-G1 BLS public key (48 bytes) registered for this validator. Zero-copy by-value return; backing storage is the ZAP buffer.

func (RegisterL1ValidatorTx) Bytes

func (t RegisterL1ValidatorTx) Bytes() []byte

func (RegisterL1ValidatorTx) Expiry

func (t RegisterL1ValidatorTx) Expiry() uint64

func (RegisterL1ValidatorTx) IsZero

func (t RegisterL1ValidatorTx) IsZero() bool

func (RegisterL1ValidatorTx) ProofOfPossession

func (t RegisterL1ValidatorTx) ProofOfPossession() [bls.SignatureLen]byte

ProofOfPossession returns the BLS signature over the public key proving the registrant controls the matching secret key.

func (RegisterL1ValidatorTx) RemainingBalanceOwnerID

func (t RegisterL1ValidatorTx) RemainingBalanceOwnerID() ids.ID

RemainingBalanceOwnerID is a v3 placeholder for the OutputOwners pointer. Batch 3 replaces this with a full OutputOwners nested-object schema (threshold + AddressIDs list).

func (RegisterL1ValidatorTx) ValidationID

func (t RegisterL1ValidatorTx) ValidationID() ids.ID

func (RegisterL1ValidatorTx) Verify added in v1.28.20

func (t RegisterL1ValidatorTx) Verify() error

Verify pins R7V7 HIGH: a RegisterL1ValidatorTx must carry a verifiable BLS proof-of-possession, a non-zero Expiry, and (if non-zero) a well-formed RemainingBalanceOwnerID. The wire-decoded buffer geometry is canonical via parseAndCheckKind; this gate fires the semantic invariants the wire layer cannot infer.

LP-023 Red round 7 R7V7 closes the gap where the wire carried BLS+Expiry+OwnerID fields but Blue's 8-tx Verify() list excluded RegisterL1ValidatorTx — defense-in-depth pairing with the mempool admission gate (R7V5) which refuses the tx at the network boundary today.

Note: per-validator RegistrationExpiry > now() is intentionally NOT enforced here. SyntacticVerify is clock-independent (executor wall-clock lives in the staking handler); this file enforces only properties that are invariant under wire encoding. The zero-Expiry gate is a syntactic floor — wire-canonically a unix timestamp can never be zero in a legitimate registration.

type RemoveChainValidatorTx

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

func NewRemoveChainValidatorTx

func NewRemoveChainValidatorTx(nodeID ids.NodeID, network ids.ID) RemoveChainValidatorTx

func WrapRemoveChainValidatorTx

func WrapRemoveChainValidatorTx(b []byte) (RemoveChainValidatorTx, error)

func (RemoveChainValidatorTx) Bytes

func (t RemoveChainValidatorTx) Bytes() []byte

func (RemoveChainValidatorTx) IsZero

func (t RemoveChainValidatorTx) IsZero() bool

func (RemoveChainValidatorTx) Network

func (t RemoveChainValidatorTx) Network() ids.ID

Network returns the L1 network ID (32B) the validator belongs to.

func (RemoveChainValidatorTx) NodeID

func (t RemoveChainValidatorTx) NodeID() ids.NodeID

type RewardValidatorTx

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

func NewRewardValidatorTx

func NewRewardValidatorTx(txID ids.ID) RewardValidatorTx

func WrapRewardValidatorTx

func WrapRewardValidatorTx(b []byte) (RewardValidatorTx, error)

func (RewardValidatorTx) Bytes

func (t RewardValidatorTx) Bytes() []byte

func (RewardValidatorTx) IsZero

func (t RewardValidatorTx) IsZero() bool

func (RewardValidatorTx) TxID

func (t RewardValidatorTx) TxID() ids.ID

type SetL1ValidatorWeightTx

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

func NewSetL1ValidatorWeightTx

func NewSetL1ValidatorWeightTx(validationID ids.ID, nonce, weight uint64) SetL1ValidatorWeightTx

func WrapSetL1ValidatorWeightTx

func WrapSetL1ValidatorWeightTx(b []byte) (SetL1ValidatorWeightTx, error)

func (SetL1ValidatorWeightTx) Bytes

func (t SetL1ValidatorWeightTx) Bytes() []byte

func (SetL1ValidatorWeightTx) IsZero

func (t SetL1ValidatorWeightTx) IsZero() bool

func (SetL1ValidatorWeightTx) Nonce

func (t SetL1ValidatorWeightTx) Nonce() uint64

func (SetL1ValidatorWeightTx) ValidationID

func (t SetL1ValidatorWeightTx) ValidationID() ids.ID

func (SetL1ValidatorWeightTx) Weight

func (t SetL1ValidatorWeightTx) Weight() uint64

type SigIndicesArray

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

SigIndicesArray is the zero-copy view over the parent tx's shared uint32 sig-index array. Each input slice is SigIndicesArray.Slice(start, count).

func SigIndicesArrayView

func SigIndicesArrayView(parent zap.Object, fieldOffset int) SigIndicesArray

SigIndicesArrayView reads the shared sig-indices array from a parent object's field offset. Uses the per-stride clamp introduced in zap v0.7.2: a poisoned length field that passes the permissive baseline gets rejected here. SizeSigIndex = 4 (each entry is a uint32 sig index) (R4V9, LP-023 Red round 4).

func (SigIndicesArray) At

func (a SigIndicesArray) At(i int) uint32

At returns the i'th uint32 sig index.

func (SigIndicesArray) IsNull

func (a SigIndicesArray) IsNull() bool

IsNull returns true if no array pointer was set.

func (SigIndicesArray) Len

func (a SigIndicesArray) Len() int

Len returns the total number of sig indices across all inputs.

func (SigIndicesArray) Slice

func (a SigIndicesArray) Slice(start, count uint32) []uint32

Slice returns the per-input signature-index window [start, start+count) as a fresh []uint32. RED-HIGH-3 (LP-023 v3.1 round 2): start and count are attacker-controlled through TransferableInput's SigIndicesStart / SigIndicesCount fields. The accessor clamps both against a.Len(); any value outside the array yields an empty slice without panicking. Callers MUST NOT index a.At() in a loop with these raw values themselves — go through Slice() so the clamp is enforced in one place.

type SignatureArray

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

SignatureArray is the zero-copy view over a parent tx's shared signature blob array. Each credential's signature slice is SignatureArray.Slice(start, count) where each blob is SigBlobSize bytes.

func SignatureArrayView

func SignatureArrayView(parent zap.Object, fieldOffset int) SignatureArray

SignatureArrayView reads the shared signature array from a parent object's field offset. Uses the per-stride clamp introduced in zap v0.7.2: a poisoned length field that passes the permissive baseline gets rejected here (R4V9, LP-023 Red round 4).

func (SignatureArray) At

At returns the i'th signature as a by-value [SigBlobSize]byte. By-value return keeps the accessor zero-allocation (the array is stack-allocated at the caller). Returns the zero array for out-of-range i.

func (SignatureArray) IsNull

func (s SignatureArray) IsNull() bool

IsNull returns true if no array pointer was set.

func (SignatureArray) Len

func (s SignatureArray) Len() int

Len returns the total number of signatures across all credentials.

func (SignatureArray) Slice

func (s SignatureArray) Slice(start, count uint32) [][SigBlobSize]byte

Slice returns the per-credential signature window [start, start+count) as a fresh [][SigBlobSize]byte. RED-HIGH-3 (LP-023 v3.1 round 2): start and count are attacker-controlled through Credential's SigsStart / SigsCount fields. The accessor clamps both against s.Len(); any value outside the array yields an empty slice without panicking. Callers MUST NOT index s.At() in a loop with these raw values themselves — go through Slice() so the clamp is enforced in one place.

type SlashValidatorTx

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

func NewSlashValidatorTx

func NewSlashValidatorTx(nodeID ids.NodeID, network ids.ID, slashPercentage uint32) SlashValidatorTx

func WrapSlashValidatorTx

func WrapSlashValidatorTx(b []byte) (SlashValidatorTx, error)

func (SlashValidatorTx) Bytes

func (t SlashValidatorTx) Bytes() []byte

func (SlashValidatorTx) IsZero

func (t SlashValidatorTx) IsZero() bool

func (SlashValidatorTx) Network

func (t SlashValidatorTx) Network() ids.ID

Network returns the L1 network ID (32B) the slashed validator belongs to. (Field stays named Network on the wire; ids.ID semantics unchanged.)

func (SlashValidatorTx) NodeID

func (t SlashValidatorTx) NodeID() ids.NodeID

func (SlashValidatorTx) SlashPercentage

func (t SlashValidatorTx) SlashPercentage() uint32

type TransferChainOwnershipTx

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

func NewTransferChainOwnershipTx

func NewTransferChainOwnershipTx(
	chain ids.ID,
	ownerThreshold uint32,
	ownerLocktime uint64,
	ownerAddress ids.ShortID,
) TransferChainOwnershipTx

func WrapTransferChainOwnershipTx

func WrapTransferChainOwnershipTx(b []byte) (TransferChainOwnershipTx, error)

func (TransferChainOwnershipTx) Bytes

func (t TransferChainOwnershipTx) Bytes() []byte

func (TransferChainOwnershipTx) Chain

func (t TransferChainOwnershipTx) Chain() ids.ID

func (TransferChainOwnershipTx) IsZero

func (t TransferChainOwnershipTx) IsZero() bool

func (TransferChainOwnershipTx) OwnerAddress

func (t TransferChainOwnershipTx) OwnerAddress() ids.ShortID

func (TransferChainOwnershipTx) OwnerLocktime

func (t TransferChainOwnershipTx) OwnerLocktime() uint64

func (TransferChainOwnershipTx) OwnerThreshold

func (t TransferChainOwnershipTx) OwnerThreshold() uint32

func (TransferChainOwnershipTx) Verify added in v1.28.20

func (t TransferChainOwnershipTx) Verify() error

Verify reconstructs an OwnerStub from a TransferChainOwnershipTx's (threshold, locktime, address) tuple and runs SyntacticVerify on it. The tx carries Owner fields inline but had no Verify() until LP-023 Red round 6 R6V8 — every other Owner-bearing tx is gated, and skipping this one allowed an adversary to publish a chain-ownership transfer with threshold=0 (no signer required) or threshold>1 (unsatisfiable, DoS).

Note: TransferChainOwnershipTx pins a single-address Owner in v3 (the most common configuration), so OwnerStub.SyntacticVerify is the right gate — it accepts threshold=1 only.

type TransferableInput

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

TransferableInput is the zero-copy view over one entry in an InputList.

READ-ONLY: backed by the underlying ZAP buffer. Mutation corrupts the parsed tx and breaks TxID = hash(buffer). Use append([]byte(nil), ...) to take ownership of any returned slice.

func (TransferableInput) Amount

func (t TransferableInput) Amount() uint64

Amount returns the input amount.

func (TransferableInput) AssetID

func (t TransferableInput) AssetID() ids.ID

AssetID returns the asset identifier.

func (TransferableInput) OutputIndex

func (t TransferableInput) OutputIndex() uint32

OutputIndex returns the spent UTXO's output index.

func (TransferableInput) SigIndicesCount

func (t TransferableInput) SigIndicesCount() uint32

SigIndicesCount returns the count of signature indices for this input.

func (TransferableInput) SigIndicesStart

func (t TransferableInput) SigIndicesStart() uint32

SigIndicesStart returns the start index into the parent tx's shared SigIndices uint32 array for this input's signature-index slice.

func (TransferableInput) TxID

func (t TransferableInput) TxID() ids.ID

TxID returns the spent UTXO's tx id (32B).

type TransferableOutput

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

TransferableOutput is the zero-copy view over one entry in an OutputList.

func (TransferableOutput) Amount

func (t TransferableOutput) Amount() uint64

Amount returns the asset amount.

func (TransferableOutput) AssetID

func (t TransferableOutput) AssetID() ids.ID

AssetID returns the asset identifier (32B).

func (TransferableOutput) Locktime

func (t TransferableOutput) Locktime() uint64

Locktime returns the unix timestamp before which the output is spendable only by the locktime-clearing path.

func (TransferableOutput) OwnerAddress

func (t TransferableOutput) OwnerAddress() ids.ShortID

OwnerAddress returns the single owner address (v3 stub form). Multi-address outputs travel through the legacy codec gate.

func (TransferableOutput) Threshold

func (t TransferableOutput) Threshold() uint32

Threshold returns the owner-threshold (signatures-required count).

type TransformChainTx

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

func NewTransformChainTx

func NewTransformChainTx(in TransformChainTxInput) TransformChainTx

func WrapTransformChainTx

func WrapTransformChainTx(b []byte) (TransformChainTx, error)

func (TransformChainTx) AssetID

func (t TransformChainTx) AssetID() ids.ID

func (TransformChainTx) BlockchainID

func (t TransformChainTx) BlockchainID() ids.ID

func (TransformChainTx) Bytes

func (t TransformChainTx) Bytes() []byte

func (TransformChainTx) Chain

func (t TransformChainTx) Chain() ids.ID

func (TransformChainTx) Credentials

func (t TransformChainTx) Credentials() CredentialList

func (TransformChainTx) InitialSupply

func (t TransformChainTx) InitialSupply() uint64

func (TransformChainTx) Ins

func (t TransformChainTx) Ins() InputList

func (TransformChainTx) IsZero

func (t TransformChainTx) IsZero() bool

func (TransformChainTx) MaxConsumptionRate

func (t TransformChainTx) MaxConsumptionRate() uint64

func (TransformChainTx) MaxStakeDuration

func (t TransformChainTx) MaxStakeDuration() uint32

func (TransformChainTx) MaxValidatorStake

func (t TransformChainTx) MaxValidatorStake() uint64

func (TransformChainTx) MaxValidatorWeightFactor

func (t TransformChainTx) MaxValidatorWeightFactor() uint8

func (TransformChainTx) MaximumSupply

func (t TransformChainTx) MaximumSupply() uint64

func (TransformChainTx) Memo

func (t TransformChainTx) Memo() []byte

func (TransformChainTx) MinConsumptionRate

func (t TransformChainTx) MinConsumptionRate() uint64

func (TransformChainTx) MinDelegationFee

func (t TransformChainTx) MinDelegationFee() uint32

func (TransformChainTx) MinDelegatorStake

func (t TransformChainTx) MinDelegatorStake() uint64

func (TransformChainTx) MinStakeDuration

func (t TransformChainTx) MinStakeDuration() uint32

func (TransformChainTx) MinValidatorStake

func (t TransformChainTx) MinValidatorStake() uint64

func (TransformChainTx) NetworkID

func (t TransformChainTx) NetworkID() uint32

func (TransformChainTx) Outs

func (t TransformChainTx) Outs() OutputList

func (TransformChainTx) SigIndicesArray

func (t TransformChainTx) SigIndicesArray() SigIndicesArray

func (TransformChainTx) SignatureArray

func (t TransformChainTx) SignatureArray() SignatureArray

func (TransformChainTx) UptimeRequirement

func (t TransformChainTx) UptimeRequirement() uint32

type TransformChainTxInput

type TransformChainTxInput struct {
	NetworkID                uint32
	BlockchainID             ids.ID
	Outs                     []OutputListEntry
	Ins                      []InputListEntry
	Credentials              []CredentialListEntry
	Memo                     []byte
	Chain                    ids.ID
	AssetID                  ids.ID
	InitialSupply            uint64
	MaximumSupply            uint64
	MinConsumptionRate       uint64
	MaxConsumptionRate       uint64
	MinValidatorStake        uint64
	MaxValidatorStake        uint64
	MinStakeDuration         uint32
	MaxStakeDuration         uint32
	MinDelegationFee         uint32
	MinDelegatorStake        uint64
	MaxValidatorWeightFactor uint8
	UptimeRequirement        uint32
}

type TxKind

type TxKind uint8

TxKind is the 1-byte tx-type discriminator stored at offset 0 of every zap_native tx's fixed section. Wrap*Tx functions verify the kind matches the expected value before returning a typed accessor; constructors write the kind unconditionally. This closes the cross-tx-type confusion surface where an AdvanceTimeTx buffer could be Wrap'd as a BaseTx and return garbage-but-deterministic field reads.

Schema v3 lays out every fixed section with TxKind at offset 0; all other fields shift by +1 byte vs v2. TxKind values are dense, never reused, and 0 is reserved (rejected by Wrap*).

const (
	TxKindReserved                   TxKind = 0
	TxKindAdvanceTime                TxKind = 1
	TxKindRewardValidator            TxKind = 2
	TxKindSetL1ValidatorWeight       TxKind = 3
	TxKindIncreaseL1ValidatorBalance TxKind = 4
	TxKindDisableL1Validator         TxKind = 5
	TxKindBase                       TxKind = 6
	TxKindRegisterL1Validator        TxKind = 7
	TxKindSlashValidator             TxKind = 8
	TxKindTransferChainOwnership     TxKind = 9
	TxKindRemoveChainValidator       TxKind = 10
	// Batch 3 — tx types that compose batch-3 list/object primitives:
	TxKindBaseFull                   TxKind = 11 // BaseTx with Outs+Ins+Credentials
	TxKindAddPermissionlessValidator TxKind = 12
	TxKindImport                     TxKind = 13
	TxKindExport                     TxKind = 14
	TxKindCreateChain                TxKind = 15
	// Batch 4 — remaining P-chain tx types:
	TxKindAddValidator               TxKind = 16 // pre-Etna legacy validator add
	TxKindAddDelegator               TxKind = 17 // pre-Etna legacy delegator add
	TxKindAddPermissionlessDelegator TxKind = 18 // Etna+ permissionless delegator
	TxKindAddChainValidator          TxKind = 19 // chain/subnet validator add (rebranded from AddSubnetValidator)
	TxKindCreateNetwork              TxKind = 20 // create a network (rebranded from CreateSubnet)
	TxKindTransformChain             TxKind = 21 // transform chain config (rebranded from TransformSubnet)
	TxKindConvertNetworkToL1         TxKind = 22 // convert network → L1 (rebranded from ConvertSubnetToL1)
	TxKindCreateSovereignL1          TxKind = 23 // create sovereign L1
)

type ValidatorRecord

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

ValidatorRecord is the zero-copy WIRE view over one initial-validator record. All fields are fixed-size so there is no Bind() step — every accessor is safe to call directly.

CONSUMER SAFETY: BLSPubKey and BLSPoP are returned as COPIED []byte (not aliasing the parent buffer). Consumers may mutate the returned slices without corrupting subsequent reads. The signature verification (BLS pairing) is the consumer's responsibility.

ZERO-VALUE SAFETY: `ValidatorRecord{}` (returned by ValidatorsList.At on out-of-range / clamped lists) is detectable via IsNull(); calling any accessor on a zero-value record returns the zero value (NodeID=0, Weight=0, empty BLS fields) instead of panicking.

func (ValidatorRecord) BLSPoP

func (r ValidatorRecord) BLSPoP() []byte

BLSPoP returns the validator's BLS proof-of-possession (G2 compressed, 96B). The PoP binds the validator's BLS keypair to their NodeID and must be verified before registering the validator on the L1. The returned slice is a COPY — consumer mutation does not affect subsequent reads or the underlying ZAP buffer. Returns an empty slice on a zero-value record.

func (ValidatorRecord) BLSPubKey

func (r ValidatorRecord) BLSPubKey() []byte

BLSPubKey returns the validator's BLS public key (G1 compressed, 48B). The returned slice is a COPY — consumer mutation does not affect subsequent reads or the underlying ZAP buffer. Returns an empty slice on a zero-value record.

func (ValidatorRecord) IsNull

func (r ValidatorRecord) IsNull() bool

IsNull returns true if the record is the zero value. Accessors on a zero-value record return zero rather than panic — callers may still want to short-circuit downstream work on IsNull records.

func (ValidatorRecord) NodeID

func (r ValidatorRecord) NodeID() ids.NodeID

NodeID returns the validator's NodeID. Returns zero on a zero-value record.

func (ValidatorRecord) RegistrationExpiry

func (r ValidatorRecord) RegistrationExpiry() uint64

RegistrationExpiry returns the unix timestamp by which the validator must register on the new L1. If the L1 hasn't accepted the registration by this time, the slot expires. Returns 0 on a zero-value record.

func (ValidatorRecord) Weight

func (r ValidatorRecord) Weight() uint64

Weight returns the validator's stake weight. Returns 0 on a zero-value record.

type ValidatorsList

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

ValidatorsList is the zero-copy WIRE view over a list of ValidatorRecord items. Fixed-stride only — no sibling arrays needed.

Uses Object.ListStride from zap v0.7.2 for per-element clamp: a poisoned length field that passes the permissive baseline gets rejected here (R4V9, LP-023 Red round 4).

func NewValidatorsListView

func NewValidatorsListView(parent zap.Object, fieldOffset int) ValidatorsList

NewValidatorsListView reads a ValidatorsList from a parent object's field offset. Uses the per-stride clamp (R4V9).

func (ValidatorsList) At

At returns the i'th ValidatorRecord. Returns zero-value ValidatorRecord when out of range — accessor calls on the zero value return zero fields rather than panicking.

func (ValidatorsList) IsNull

func (l ValidatorsList) IsNull() bool

IsNull returns true if no list pointer was set.

func (ValidatorsList) Len

func (l ValidatorsList) Len() int

Len returns the validator count.

type ValidatorsListEntry

type ValidatorsListEntry struct {
	NodeID             ids.NodeID
	Weight             uint64
	BLSPubKey          [BLSPubKeySize]byte
	BLSPoP             [BLSPoPSize]byte
	RegistrationExpiry uint64
}

ValidatorsListEntry is the constructor input for a ValidatorsList. Each entry pins one initial validator; fields map 1:1 to the wire record.

type WarpMessage

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

WarpMessage is the zero-copy view over a WarpMessage object embedded in a parent tx.

func WarpMessageView

func WarpMessageView(parent zap.Object, fieldOffset int) WarpMessage

WarpMessageView reads a WarpMessage from a parent object's field offset.

func (WarpMessage) IsNull

func (m WarpMessage) IsNull() bool

IsNull returns true if no message pointer was set.

func (WarpMessage) Payload

func (m WarpMessage) Payload() []byte

Payload returns the addressed-call payload bytes.

READ-ONLY: the returned slice aliases the underlying ZAP buffer. Mutation corrupts the parsed tx and breaks TxID = hash(buffer). To own the bytes, copy first: append([]byte(nil), p...).

func (WarpMessage) SourceNetwork

func (m WarpMessage) SourceNetwork() ids.ID

SourceNetwork returns the originating network identifier.

Jump to

Keyboard shortcuts

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