mirror of
https://github.com/luxfi/chains.git
synced 2026-09-24 00:26:00 +00:00
Replaces raft's serialization role for volume/fileId allocation with
owner-gated VM state riding native Lux consensus. The HRW owner of a range
is the only emitter of allocate mutations, enforced at block Verify — no
leader election.
- txs: AllocateTx{Range,Count} mirrors PutManifestTx codec (type byte + JSON);
Verify rejects empty range / zero count. Owner gate is block-level, not in
the tx (a tx cannot see the block's validator set).
- state: per-range counter alloc/<range> (GetAlloc/SetAlloc), folded into the
SHAKE256 state Root() alongside manifests via rootPrefixes; domain bumped to
SCHAIN_STATE_ROOT_V2 so the root covers allocator divergence.
- vm: applyAllocate increments alloc/<range> by Count, reserving [base,base+Count)
— pure function of committed state, deterministic, version-layer only, no I/O.
Owner gate: pinning.IsOwner(range, proposer, members) in ProcessBlock; a
non-owner (or no-validator-set) allocate fails the whole block. ProcessBlock
now Aborts staged state first so read-modify-write applies over COMMITTED
state (idempotent across BuildBlock+Verify re-application).
- BlockContext{Members,Proposer,Epoch} threads the validator set + proposer as
explicit deterministic inputs (no network I/O in Verify). BlockContextBuilder
is the seam to the real consensus runtime (master-cutover stage); empty
context = M0/no-allocate path, AllocateTx fails closed.
Tests (green, no go.sum bypass):
- owner allocates: contiguous + monotonic across blocks ([0,8) then [8,13)).
- non-owner rejected: proposer-side (BuildBlock) and verifier-side (Verify) →
errNonOwnerAllocate; counter untouched; nothing leaks to durable base.
- empty validator set: fails closed (errNoValidatorSet).
- parallel distinct ranges: independent owners allocate independently.
- same range: serializes through its one owner.
- state root covers alloc: counter change moves Root(); Verify rejects a
tampered claimed root (errStateRootMismatch).