mirror of
https://github.com/luxfi/node.git
synced 2026-10-30 15:24:05 +00:00
Its transactions were the named job and are done; what was left was everything else the chain writes. Three more schemas, and the offsets are out of the source entirely. chains/schema/warp.zap — the warp envelope, the payloads it carries, and the conversion preimage an L1's id is the hash of. Eleven structs across warp.rs and warpmsg.rs, and the differential still reproduces the warp message Go wrote, byte for byte. chains/schema/state.zap — what a P node writes to its own disk. Separate from the wire on purpose: a change to a wire schema is a fork, a change to this one is a migration, and one file per consequence is how you can tell which you just made. The rest went into pchain.zap: the fx primitives the chain spends when they travel alone rather than inside a transaction, the standalone owner key a locked balance is tallied under, and a genesis blob. TWO THINGS THE SCHEMAS HAD TO SAY OUT LOUD, and would have moved bytes otherwise. The stored Staker reserves sixteen bytes past its last field — it always has, and a schema that stopped at the public key would write a shorter record than every record already on disk, so those bytes are named Reserved for the same reason Out and In name their Pad. And the P-chain's standalone owner key is NOT the fx owner shape: the same two fields in the other order, because one is a key and one is a wire. Naming them apart is what keeps a reader from finding a threshold where a locktime is. TransferOutput and Utxo are now declared in two schemas — xchain.zap and pchain.zap — because the X-chain makes them and the P-chain spends them. That is two statements of one format and it is the wrong number. The right number needs an import across schemas that zapgen does not have, and cannot get cheaply: xchain.zap's own envelope holds list<ptr<TransferableOut>>, so the reference cannot be moved away from the file that declares it. Until then chains/rust/zap/tests/one_format.rs reads both schemas and fails the day the two declarations drift — which is the day before a P node and an X node stop agreeing about a UTXO. Its negative control was run: change one offset in one file and it fails, naming the struct. WHAT IS LEFT. Nothing. No Rust chain hand-writes a wire shape any more. The only remaining calls to the builder outside a generated module are two tests crafting deliberate buffers to feed a reader, which is where a hand-built object belongs, and two generic list helpers that take a builder and know nothing about any shape. 424 platformvm tests including the warp and chain differentials, the corpus byte test and the hostile-bytes fuzz; `make wire` verified a fixed point over all seven schemas.
75 lines
2.3 KiB
Plaintext
75 lines
2.3 KiB
Plaintext
# SPDX-License-Identifier: BSD-3-Clause-Eco
|
|
# What the P-chain writes down.
|
|
#
|
|
# These are records in this node's own store, not messages between nodes: a
|
|
# peer never sees them, and Go's store writes its own layout. They are stated
|
|
# here for the same reason the wire is — the offsets ARE the format, and a
|
|
# record read at the wrong offset is a validator with the wrong weight, found
|
|
# at the next restart rather than at the write.
|
|
#
|
|
# Nothing here is consensus. A change to this file rewrites what a node reads
|
|
# back from its own disk, which is a migration; a change to a wire schema is a
|
|
# fork. They are separate files because they are separate consequences.
|
|
|
|
package state
|
|
|
|
type id32 = bytes_fixed[32]
|
|
type addr = bytes_fixed[20]
|
|
|
|
# An owner set, as it is stored: the addresses are one flat run rather than a
|
|
# list, because nothing indexes into them here.
|
|
struct Owners {
|
|
Locktime u64 @0
|
|
Threshold u32 @8
|
|
Addresses bytes @16
|
|
}
|
|
|
|
# One staker. The key is present or it is not — a validator registered before
|
|
# keys existed has none, and an all-zero key would be a key that verifies
|
|
# nothing, so a byte says which and the run says what.
|
|
struct Staker {
|
|
Weight u64 @0
|
|
Start u64 @8
|
|
End u64 @16
|
|
Reward u64 @24
|
|
Next u64 @32
|
|
Priority u8 @40
|
|
HasKey u8 @41
|
|
PublicKey bytes @48
|
|
# Sixteen bytes past the last field. The record has always reserved them
|
|
# and no field has ever covered them, so naming them is what keeps the
|
|
# emitted size the size already on disk — a schema that stopped at the
|
|
# public key would write a shorter record than every record already
|
|
# written.
|
|
Reserved bytes_fixed[16] @56
|
|
}
|
|
|
|
struct L1Validator {
|
|
Chain id32 @0
|
|
NodeID addr @32
|
|
Start u64 @56
|
|
Weight u64 @64
|
|
MinNonce u64 @72
|
|
EndFee u64 @80
|
|
PublicKey bytes @88
|
|
RemainingOwner bytes @96
|
|
DisableOwner bytes @104
|
|
}
|
|
|
|
struct Conversion {
|
|
ConversionID id32 @0
|
|
Chain id32 @32
|
|
Address bytes @64
|
|
}
|
|
|
|
# One pending change to a validator set: how the weight moved, whether the key
|
|
# changed, and the two keys it moved between.
|
|
struct Change {
|
|
Amount u64 @0
|
|
Decrease u8 @8
|
|
Renamed u8 @9
|
|
Validation id32 @16
|
|
KeyBefore bytes @48
|
|
KeyAfter bytes @56
|
|
}
|