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
- Variables
- func IsZAPBytes(b []byte) bool
- func NewOwnerInline(b *zap.Builder, in OwnerInput) (threshold uint32, locktime uint64, addrListOff, addrListLen int, err error)
- func ShouldUseZAPForWrite(blockTimestamp uint64) bool
- func WriteAddressList(b *zap.Builder, addrs []ids.ShortID) (offset, entryCount int)
- func WriteChainsList(b *zap.Builder, entries []ChainsListEntry) (listOffset, listCount int, nameBlobs []byte, fxIDsBlobs []byte, ...)
- func WriteCredentialList(b *zap.Builder, entries []CredentialListEntry) (credentialListOffset, credentialListCount int, ...)
- func WriteEvidenceList(b *zap.Builder, entries []EvidenceListEntry) (listOffset, listCount int, messageBlobs []byte, signatureBlobs []byte)
- func WriteInputList(b *zap.Builder, entries []InputListEntry) (inputListOffset, inputListCount int, sigIndicesAll []uint32)
- func WriteOutputList(b *zap.Builder, entries []OutputListEntry) (offset, entryCount int)
- func WriteSigIndicesArray(b *zap.Builder, sigs []uint32) (offset, entryCount int)
- func WriteSignatureArray(b *zap.Builder, sigs [][SigBlobSize]byte) (offset, entryCount int)
- func WriteValidatorsList(b *zap.Builder, entries []ValidatorsListEntry) (offset, count int)
- func WriteWarpMessage(b *zap.Builder, sourceNetwork ids.ID, payload []byte) int
- type AddChainValidatorTx
- func (t AddChainValidatorTx) BlockchainID() ids.ID
- func (t AddChainValidatorTx) Bytes() []byte
- func (t AddChainValidatorTx) Chain() ids.ID
- func (t AddChainValidatorTx) Credentials() CredentialList
- func (t AddChainValidatorTx) Ins() InputList
- func (t AddChainValidatorTx) IsZero() bool
- func (t AddChainValidatorTx) Memo() []byte
- func (t AddChainValidatorTx) NetworkID() uint32
- func (t AddChainValidatorTx) NodeID() ids.NodeID
- func (t AddChainValidatorTx) Outs() OutputList
- func (t AddChainValidatorTx) SigIndicesArray() SigIndicesArray
- func (t AddChainValidatorTx) SignatureArray() SignatureArray
- func (t AddChainValidatorTx) StakeEnd() uint64
- func (t AddChainValidatorTx) StakeStart() uint64
- func (t AddChainValidatorTx) StakeWeight() uint64
- type AddChainValidatorTxInput
- type AddDelegatorTx
- func (t AddDelegatorTx) BlockchainID() ids.ID
- func (t AddDelegatorTx) Bytes() []byte
- func (t AddDelegatorTx) Credentials() CredentialList
- func (t AddDelegatorTx) DelegationRewardsOwner() (uint32, uint64, ids.ShortID)
- func (t AddDelegatorTx) Ins() InputList
- func (t AddDelegatorTx) IsZero() bool
- func (t AddDelegatorTx) Memo() []byte
- func (t AddDelegatorTx) NetworkID() uint32
- func (t AddDelegatorTx) NodeID() ids.NodeID
- func (t AddDelegatorTx) Outs() OutputList
- func (t AddDelegatorTx) SigIndicesArray() SigIndicesArray
- func (t AddDelegatorTx) SignatureArray() SignatureArray
- func (t AddDelegatorTx) StakeEnd() uint64
- func (t AddDelegatorTx) StakeOuts() OutputList
- func (t AddDelegatorTx) StakeStart() uint64
- func (t AddDelegatorTx) StakeWeight() uint64
- func (t AddDelegatorTx) Verify() error
- type AddDelegatorTxInput
- type AddPermissionlessDelegatorTx
- func (t AddPermissionlessDelegatorTx) BlockchainID() ids.ID
- func (t AddPermissionlessDelegatorTx) Bytes() []byte
- func (t AddPermissionlessDelegatorTx) Chain() ids.ID
- func (t AddPermissionlessDelegatorTx) Credentials() CredentialList
- func (t AddPermissionlessDelegatorTx) DelegationRewardsOwner() (uint32, uint64, ids.ShortID)
- func (t AddPermissionlessDelegatorTx) Ins() InputList
- func (t AddPermissionlessDelegatorTx) IsZero() bool
- func (t AddPermissionlessDelegatorTx) Memo() []byte
- func (t AddPermissionlessDelegatorTx) NetworkID() uint32
- func (t AddPermissionlessDelegatorTx) NodeID() ids.NodeID
- func (t AddPermissionlessDelegatorTx) Outs() OutputList
- func (t AddPermissionlessDelegatorTx) SigIndicesArray() SigIndicesArray
- func (t AddPermissionlessDelegatorTx) SignatureArray() SignatureArray
- func (t AddPermissionlessDelegatorTx) StakeAssetID() ids.ID
- func (t AddPermissionlessDelegatorTx) StakeEnd() uint64
- func (t AddPermissionlessDelegatorTx) StakeOuts() OutputList
- func (t AddPermissionlessDelegatorTx) StakeStart() uint64
- func (t AddPermissionlessDelegatorTx) StakeWeight() uint64
- func (t AddPermissionlessDelegatorTx) Verify() error
- type AddPermissionlessDelegatorTxInput
- type AddPermissionlessValidatorTx
- func (t AddPermissionlessValidatorTx) BLSProofOfPossession() [bls.SignatureLen]byte
- func (t AddPermissionlessValidatorTx) BLSPublicKey() [bls.PublicKeyLen]byte
- func (t AddPermissionlessValidatorTx) BlockchainID() ids.ID
- func (t AddPermissionlessValidatorTx) Bytes() []byte
- func (t AddPermissionlessValidatorTx) Credentials() CredentialList
- func (t AddPermissionlessValidatorTx) DelegationRewardsOwner() (uint32, uint64, ids.ShortID)
- func (t AddPermissionlessValidatorTx) DelegationShares() uint32
- func (t AddPermissionlessValidatorTx) Ins() InputList
- func (t AddPermissionlessValidatorTx) IsZero() bool
- func (t AddPermissionlessValidatorTx) Memo() []byte
- func (t AddPermissionlessValidatorTx) NetworkID() uint32
- func (t AddPermissionlessValidatorTx) NodeID() ids.NodeID
- func (t AddPermissionlessValidatorTx) Outs() OutputList
- func (t AddPermissionlessValidatorTx) SigIndicesArray() SigIndicesArray
- func (t AddPermissionlessValidatorTx) SignatureArray() SignatureArray
- func (t AddPermissionlessValidatorTx) StakeAmount() uint64
- func (t AddPermissionlessValidatorTx) StakeAssetID() ids.ID
- func (t AddPermissionlessValidatorTx) StakeEnd() uint64
- func (t AddPermissionlessValidatorTx) StakeStart() uint64
- func (t AddPermissionlessValidatorTx) StakeWeight() uint64
- func (t AddPermissionlessValidatorTx) ValidationRewardsOwner() (uint32, uint64, ids.ShortID)
- func (t AddPermissionlessValidatorTx) Verify() error
- type AddPermissionlessValidatorTxInput
- type AddValidatorTx
- func (t AddValidatorTx) BlockchainID() ids.ID
- func (t AddValidatorTx) Bytes() []byte
- func (t AddValidatorTx) Credentials() CredentialList
- func (t AddValidatorTx) DelegationShares() uint32
- func (t AddValidatorTx) Ins() InputList
- func (t AddValidatorTx) IsZero() bool
- func (t AddValidatorTx) Memo() []byte
- func (t AddValidatorTx) NetworkID() uint32
- func (t AddValidatorTx) NodeID() ids.NodeID
- func (t AddValidatorTx) Outs() OutputList
- func (t AddValidatorTx) RewardsOwner() (uint32, uint64, ids.ShortID)
- func (t AddValidatorTx) SigIndicesArray() SigIndicesArray
- func (t AddValidatorTx) SignatureArray() SignatureArray
- func (t AddValidatorTx) StakeEnd() uint64
- func (t AddValidatorTx) StakeOuts() OutputList
- func (t AddValidatorTx) StakeStart() uint64
- func (t AddValidatorTx) StakeWeight() uint64
- func (t AddValidatorTx) Verify() error
- type AddValidatorTxInput
- type AddressList
- type AdvanceTimeTx
- type BaseTx
- type BaseTxFull
- func (t BaseTxFull) BlockchainID() ids.ID
- func (t BaseTxFull) Bytes() []byte
- func (t BaseTxFull) Credentials() CredentialList
- func (t BaseTxFull) Ins() InputList
- func (t BaseTxFull) IsZero() bool
- func (t BaseTxFull) Memo() []byte
- func (t BaseTxFull) NetworkID() uint32
- func (t BaseTxFull) Outs() OutputList
- func (t BaseTxFull) SigIndicesArray() SigIndicesArray
- func (t BaseTxFull) SignatureArray() SignatureArray
- type BaseTxFullInput
- type BoundChainEntry
- type BoundChainsList
- type BoundEvidenceEntry
- type BoundEvidenceList
- type ChainEntry
- type ChainsListEntry
- type ChainsListView
- type ConvertNetworkToL1Tx
- func (t ConvertNetworkToL1Tx) Address() []byte
- func (t ConvertNetworkToL1Tx) BlockchainID() ids.ID
- func (t ConvertNetworkToL1Tx) Bytes() []byte
- func (t ConvertNetworkToL1Tx) Chain() ids.ID
- func (t ConvertNetworkToL1Tx) Credentials() CredentialList
- func (t ConvertNetworkToL1Tx) Ins() InputList
- func (t ConvertNetworkToL1Tx) IsZero() bool
- func (t ConvertNetworkToL1Tx) ManagerChainID() ids.ID
- func (t ConvertNetworkToL1Tx) Memo() []byte
- func (t ConvertNetworkToL1Tx) NetworkID() uint32
- func (t ConvertNetworkToL1Tx) Outs() OutputList
- func (t ConvertNetworkToL1Tx) SigIndicesArray() SigIndicesArray
- func (t ConvertNetworkToL1Tx) SignatureArray() SignatureArray
- func (t ConvertNetworkToL1Tx) Validators() ValidatorsList
- func (t ConvertNetworkToL1Tx) Verify() error
- type ConvertNetworkToL1TxInput
- type CreateChainTx
- func (t CreateChainTx) BlockchainID() ids.ID
- func (t CreateChainTx) Bytes() []byte
- func (t CreateChainTx) Credentials() CredentialList
- func (t CreateChainTx) GenesisData() []byte
- func (t CreateChainTx) Ins() InputList
- func (t CreateChainTx) IsZero() bool
- func (t CreateChainTx) Memo() []byte
- func (t CreateChainTx) NetworkID() uint32
- func (t CreateChainTx) Outs() OutputList
- func (t CreateChainTx) Owner() (uint32, uint64, ids.ShortID)
- func (t CreateChainTx) ParentNetwork() ids.ID
- func (t CreateChainTx) SigIndicesArray() SigIndicesArray
- func (t CreateChainTx) SignatureArray() SignatureArray
- func (t CreateChainTx) VMID() ids.ID
- func (t CreateChainTx) Verify() error
- func (t CreateChainTx) WarpMessageHash() ids.ID
- type CreateChainTxInput
- type CreateNetworkTx
- func (t CreateNetworkTx) BlockchainID() ids.ID
- func (t CreateNetworkTx) Bytes() []byte
- func (t CreateNetworkTx) Credentials() CredentialList
- func (t CreateNetworkTx) Ins() InputList
- func (t CreateNetworkTx) IsZero() bool
- func (t CreateNetworkTx) Memo() []byte
- func (t CreateNetworkTx) NetworkID() uint32
- func (t CreateNetworkTx) Outs() OutputList
- func (t CreateNetworkTx) Owner() (uint32, uint64, ids.ShortID)
- func (t CreateNetworkTx) SigIndicesArray() SigIndicesArray
- func (t CreateNetworkTx) SignatureArray() SignatureArray
- func (t CreateNetworkTx) Verify() error
- type CreateNetworkTxInput
- type CreateSovereignL1Tx
- func (t CreateSovereignL1Tx) BlockchainID() ids.ID
- func (t CreateSovereignL1Tx) BoundChains() BoundChainsList
- func (t CreateSovereignL1Tx) Bytes() []byte
- func (t CreateSovereignL1Tx) Chains() ChainsListView
- func (t CreateSovereignL1Tx) Credentials() CredentialList
- func (t CreateSovereignL1Tx) FxIDsBlobs() []byte
- func (t CreateSovereignL1Tx) GenesisDataBlobs() []byte
- func (t CreateSovereignL1Tx) Ins() InputList
- func (t CreateSovereignL1Tx) IsZero() bool
- func (t CreateSovereignL1Tx) ManagerAddress() []byte
- func (t CreateSovereignL1Tx) ManagerChainIdx() uint32
- func (t CreateSovereignL1Tx) Memo() []byte
- func (t CreateSovereignL1Tx) NameBlobs() []byte
- func (t CreateSovereignL1Tx) NetworkID() uint32
- func (t CreateSovereignL1Tx) Outs() OutputList
- func (t CreateSovereignL1Tx) Owner() (uint32, uint64, ids.ShortID)
- func (t CreateSovereignL1Tx) SigIndicesArray() SigIndicesArray
- func (t CreateSovereignL1Tx) SignatureArray() SignatureArray
- func (t CreateSovereignL1Tx) Validators() ValidatorsList
- func (t CreateSovereignL1Tx) Verify() error
- type CreateSovereignL1TxInput
- type Credential
- type CredentialList
- type CredentialListEntry
- type DisableL1ValidatorTx
- type EvidenceEntry
- func (e EvidenceEntry) EvidenceType() uint8
- func (e EvidenceEntry) Height() uint64
- func (e EvidenceEntry) MessageARange() (uint32, uint32)
- func (e EvidenceEntry) MessageBRange() (uint32, uint32)
- func (e EvidenceEntry) SignatureARange() (uint32, uint32)
- func (e EvidenceEntry) SignatureBRange() (uint32, uint32)
- type EvidenceListEntry
- type EvidenceListView
- type ExportTx
- func (t ExportTx) BlockchainID() ids.ID
- func (t ExportTx) Bytes() []byte
- func (t ExportTx) Credentials() CredentialList
- func (t ExportTx) DestinationNetwork() ids.ID
- func (t ExportTx) ExportedOutsRange() (uint32, uint32)
- func (t ExportTx) Ins() InputList
- func (t ExportTx) IsZero() bool
- func (t ExportTx) Memo() []byte
- func (t ExportTx) NetworkID() uint32
- func (t ExportTx) Outs() OutputList
- func (t ExportTx) SigIndicesArray() SigIndicesArray
- func (t ExportTx) SignatureArray() SignatureArray
- type ExportTxInput
- type ImportTx
- func (t ImportTx) BlockchainID() ids.ID
- func (t ImportTx) Bytes() []byte
- func (t ImportTx) Credentials() CredentialList
- func (t ImportTx) ImportedInsRange() (uint32, uint32)
- func (t ImportTx) Ins() InputList
- func (t ImportTx) IsZero() bool
- func (t ImportTx) Memo() []byte
- func (t ImportTx) NetworkID() uint32
- func (t ImportTx) Outs() OutputList
- func (t ImportTx) SigIndicesArray() SigIndicesArray
- func (t ImportTx) SignatureArray() SignatureArray
- func (t ImportTx) SourceNetwork() ids.ID
- type ImportTxInput
- type IncreaseL1ValidatorBalanceTx
- type InputList
- type InputListEntry
- type OutputList
- type OutputListEntry
- type Owner
- type OwnerInput
- type OwnerStub
- type RegisterL1ValidatorTx
- func (t RegisterL1ValidatorTx) BLSPublicKey() [bls.PublicKeyLen]byte
- func (t RegisterL1ValidatorTx) Bytes() []byte
- func (t RegisterL1ValidatorTx) Expiry() uint64
- func (t RegisterL1ValidatorTx) IsZero() bool
- func (t RegisterL1ValidatorTx) ProofOfPossession() [bls.SignatureLen]byte
- func (t RegisterL1ValidatorTx) RemainingBalanceOwnerID() ids.ID
- func (t RegisterL1ValidatorTx) ValidationID() ids.ID
- func (t RegisterL1ValidatorTx) Verify() error
- type RemoveChainValidatorTx
- type RewardValidatorTx
- type SetL1ValidatorWeightTx
- type SigIndicesArray
- type SignatureArray
- type SlashValidatorTx
- type TransferChainOwnershipTx
- func (t TransferChainOwnershipTx) Bytes() []byte
- func (t TransferChainOwnershipTx) Chain() ids.ID
- func (t TransferChainOwnershipTx) IsZero() bool
- func (t TransferChainOwnershipTx) OwnerAddress() ids.ShortID
- func (t TransferChainOwnershipTx) OwnerLocktime() uint64
- func (t TransferChainOwnershipTx) OwnerThreshold() uint32
- func (t TransferChainOwnershipTx) Verify() error
- type TransferableInput
- type TransferableOutput
- type TransformChainTx
- func (t TransformChainTx) AssetID() ids.ID
- func (t TransformChainTx) BlockchainID() ids.ID
- func (t TransformChainTx) Bytes() []byte
- func (t TransformChainTx) Chain() ids.ID
- func (t TransformChainTx) Credentials() CredentialList
- func (t TransformChainTx) InitialSupply() uint64
- func (t TransformChainTx) Ins() InputList
- func (t TransformChainTx) IsZero() bool
- func (t TransformChainTx) MaxConsumptionRate() uint64
- func (t TransformChainTx) MaxStakeDuration() uint32
- func (t TransformChainTx) MaxValidatorStake() uint64
- func (t TransformChainTx) MaxValidatorWeightFactor() uint8
- func (t TransformChainTx) MaximumSupply() uint64
- func (t TransformChainTx) Memo() []byte
- func (t TransformChainTx) MinConsumptionRate() uint64
- func (t TransformChainTx) MinDelegationFee() uint32
- func (t TransformChainTx) MinDelegatorStake() uint64
- func (t TransformChainTx) MinStakeDuration() uint32
- func (t TransformChainTx) MinValidatorStake() uint64
- func (t TransformChainTx) NetworkID() uint32
- func (t TransformChainTx) Outs() OutputList
- func (t TransformChainTx) SigIndicesArray() SigIndicesArray
- func (t TransformChainTx) SignatureArray() SignatureArray
- func (t TransformChainTx) UptimeRequirement() uint32
- type TransformChainTxInput
- type TxKind
- type ValidatorRecord
- type ValidatorsList
- type ValidatorsListEntry
- type WarpMessage
Constants ¶
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)
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
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
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 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
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 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
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).
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)
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.
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).
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)
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
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
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)
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)
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
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.
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
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:
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
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].
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.
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.
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)
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)
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.
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
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
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.
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
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.
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.
const OffsetTxKind = 0
OffsetTxKind is the fixed wire position of the discriminator. Every zap_native fixed section reserves byte 0 for TxKind.
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.
const SizeSigIndex = 4
SizeSigIndex is the stride of a single uint32 sig index in the shared SigIndices array. Used by SigIndicesArrayView's ListStride clamp.
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 ¶
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.
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.
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.
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.
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).
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.
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.
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 ¶
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 ¶
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 ¶
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 ¶
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 ¶
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 NewAddChainValidatorTx ¶
func NewAddChainValidatorTx(in AddChainValidatorTxInput) AddChainValidatorTx
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 (t AddChainValidatorTx) Ins() InputList
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 (t AddChainValidatorTx) Outs() OutputList
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 NewAddPermissionlessDelegatorTx ¶
func NewAddPermissionlessDelegatorTx(in AddPermissionlessDelegatorTxInput) AddPermissionlessDelegatorTx
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 (t AddPermissionlessDelegatorTx) Chain() ids.ID
func (AddPermissionlessDelegatorTx) Credentials ¶
func (t AddPermissionlessDelegatorTx) Credentials() CredentialList
func (AddPermissionlessDelegatorTx) DelegationRewardsOwner ¶
func (t AddPermissionlessDelegatorTx) DelegationRewardsOwner() (uint32, uint64, ids.ShortID)
func (AddPermissionlessDelegatorTx) Ins ¶
func (t AddPermissionlessDelegatorTx) Ins() InputList
func (AddPermissionlessDelegatorTx) IsZero ¶
func (t AddPermissionlessDelegatorTx) IsZero() bool
func (AddPermissionlessDelegatorTx) Memo ¶
func (t AddPermissionlessDelegatorTx) Memo() []byte
func (AddPermissionlessDelegatorTx) NetworkID ¶
func (t AddPermissionlessDelegatorTx) NetworkID() uint32
func (AddPermissionlessDelegatorTx) NodeID ¶
func (t AddPermissionlessDelegatorTx) NodeID() ids.NodeID
func (AddPermissionlessDelegatorTx) Outs ¶
func (t AddPermissionlessDelegatorTx) Outs() OutputList
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 (t AddPermissionlessDelegatorTx) StakeOuts() OutputList
func (AddPermissionlessDelegatorTx) StakeStart ¶
func (t AddPermissionlessDelegatorTx) StakeStart() uint64
func (AddPermissionlessDelegatorTx) StakeWeight ¶
func (t AddPermissionlessDelegatorTx) StakeWeight() uint64
func (AddPermissionlessDelegatorTx) Verify ¶
func (t AddPermissionlessDelegatorTx) Verify() error
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 NewAddPermissionlessValidatorTx ¶
func NewAddPermissionlessValidatorTx(in AddPermissionlessValidatorTxInput) AddPermissionlessValidatorTx
func WrapAddPermissionlessValidatorTx ¶
func WrapAddPermissionlessValidatorTx(b []byte) (AddPermissionlessValidatorTx, error)
func (AddPermissionlessValidatorTx) BLSProofOfPossession ¶
func (t AddPermissionlessValidatorTx) BLSProofOfPossession() [bls.SignatureLen]byte
func (AddPermissionlessValidatorTx) BLSPublicKey ¶
func (t AddPermissionlessValidatorTx) BLSPublicKey() [bls.PublicKeyLen]byte
func (AddPermissionlessValidatorTx) BlockchainID ¶
func (t AddPermissionlessValidatorTx) BlockchainID() ids.ID
func (AddPermissionlessValidatorTx) Bytes ¶
func (t AddPermissionlessValidatorTx) Bytes() []byte
func (AddPermissionlessValidatorTx) Credentials ¶
func (t AddPermissionlessValidatorTx) Credentials() CredentialList
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 (t AddPermissionlessValidatorTx) Ins() InputList
func (AddPermissionlessValidatorTx) IsZero ¶
func (t AddPermissionlessValidatorTx) IsZero() bool
func (AddPermissionlessValidatorTx) Memo ¶
func (t AddPermissionlessValidatorTx) Memo() []byte
func (AddPermissionlessValidatorTx) NetworkID ¶
func (t AddPermissionlessValidatorTx) NetworkID() uint32
func (AddPermissionlessValidatorTx) NodeID ¶
func (t AddPermissionlessValidatorTx) NodeID() ids.NodeID
func (AddPermissionlessValidatorTx) Outs ¶
func (t AddPermissionlessValidatorTx) Outs() OutputList
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 ¶
func (t AddPermissionlessValidatorTx) Verify() error
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
}
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
}
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:
- Validate each returned address is non-zero before treating it as a signer, OR
- Correlate Len() against an explicit count from a sibling field (e.g. parent tx's signer-count uint32), OR
- 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 WrapBaseTx ¶
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 ¶
BlockchainID returns the chain ID the tx executes against.
func (BaseTx) Memo ¶
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.
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) 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) 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 ¶
func (l BoundChainsList) At(i int) BoundChainEntry
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.
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 ¶
func (l BoundEvidenceList) At(i int) BoundEvidenceEntry
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.
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 ¶
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):
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.
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.
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.
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) 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 NewConvertNetworkToL1Tx ¶
func NewConvertNetworkToL1Tx(in ConvertNetworkToL1TxInput) ConvertNetworkToL1Tx
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 (t ConvertNetworkToL1Tx) Ins() InputList
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 (t ConvertNetworkToL1Tx) Outs() OutputList
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) 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) 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 NewCreateSovereignL1Tx ¶
func NewCreateSovereignL1Tx(in CreateSovereignL1TxInput) CreateSovereignL1Tx
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 ¶
func (t CreateSovereignL1Tx) Chains() ChainsListView
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 (t CreateSovereignL1Tx) Ins() InputList
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 (t CreateSovereignL1Tx) Outs() OutputList
func (CreateSovereignL1Tx) Owner ¶
func (t CreateSovereignL1Tx) Owner() (uint32, uint64, ids.ShortID)
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.
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 ¶
func (l EvidenceListView) At(i int) EvidenceEntry
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.
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 (ExportTx) BlockchainID ¶
func (ExportTx) Credentials ¶
func (t ExportTx) Credentials() CredentialList
func (ExportTx) DestinationNetwork ¶
DestinationNetwork returns the network identifier the exports flow to.
func (ExportTx) ExportedOutsRange ¶
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) 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 (ImportTx) BlockchainID ¶
func (ImportTx) Credentials ¶
func (t ImportTx) Credentials() CredentialList
func (ImportTx) ImportedInsRange ¶
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) 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 ¶
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 (t IncreaseL1ValidatorBalanceTx) Balance() uint64
func (IncreaseL1ValidatorBalanceTx) Bytes ¶
func (t IncreaseL1ValidatorBalanceTx) Bytes() []byte
func (IncreaseL1ValidatorBalanceTx) IsZero ¶
func (t IncreaseL1ValidatorBalanceTx) IsZero() bool
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 ¶
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 ¶
func (l InputList) At(i int) TransferableInput
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).
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 ¶
func (l OutputList) At(i int) TransferableOutput
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.
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 ¶
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) SyntacticVerify ¶
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.
type OwnerInput ¶
OwnerInput is the constructor input for a multi-address Owner.
type OwnerStub ¶
OwnerStub is the v3 single-address owner stub used by APV's two rewards-owner fields.
func (OwnerStub) SyntacticVerify ¶
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 ¶
func (s SignatureArray) At(i int) [SigBlobSize]byte
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 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 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 ¶
func (l ValidatorsList) At(i int) ValidatorRecord
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.
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.
Source Files
¶
- add_chain_validator_tx.go
- add_delegator_tx.go
- add_permissionless_delegator_tx.go
- add_permissionless_validator_tx.go
- add_validator_tx.go
- advance_time_tx.go
- base_tx.go
- base_tx_full.go
- chains_list.go
- codec_select.go
- convert_network_to_l1_tx.go
- create_chain_tx.go
- create_network_tx.go
- create_sovereign_l1_tx.go
- credential_list.go
- disable_l1_validator_tx.go
- encoding.go
- evidence_list.go
- export_tx.go
- import_tx.go
- increase_l1_validator_balance_tx.go
- input_list.go
- kind.go
- output_list.go
- owner.go
- register_l1_validator_tx.go
- remove_chain_validator_tx.go
- reward_validator_tx.go
- set_l1_validator_weight_tx.go
- slash_validator_tx.go
- transfer_chain_ownership_tx.go
- transform_chain_tx.go
- tx_verify.go
- validators_list.go
- warp_message.go