schain

package
v1.4.0 Latest Latest
Warning

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

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

Documentation

Overview

Package schain implements the Lux S-Chain — the STORAGE VM.

The S-Chain records object STORAGE MANIFESTS through real Lux consensus: a PutManifest mutation enters the mempool, the proposer drains it into a block, every validator deterministically applies it to a per-block version layer during Verify, and the block COMMITS the version layer to the chain's database (zapdb via the luxfi/database interface) in exactly ONE atomic batch at Accept. A manifest is durable — and GetManifest returns it — only after Accept.

M0 is the smallest end-to-end proof of that contract: no blobs, no pinning, no networking beyond the VM↔engine contract. It forks dexvm's structure and COMMIT DISCIPLINE (chains/dexvm/vm.go), stripped of the DEX's cross-chain relay/settlement machinery, which a storage VM does not have:

  • vm.db (versiondb) is the per-block state layer; vm.baseDB is the durable base it wraps (mirror of dexvm/vm.go:316-318).
  • ProcessBlock applies txs to the version layer, NO I/O, deterministic (mirror of dexvm/vm.go:542).
  • acceptBlock does ONE db.CommitBatch() + batch.Write() then db.Abort() (mirror of dexvm/vm.go:1194 — its no-shared-memory branch).

DESIGN: no background goroutines; every operation is block-driven and deterministic, so every node produces identical state from identical inputs.

Index

Constants

This section is empty.

Variables

View Source
var (
	// VMID is the unique identifier for the S-Chain storage VM. Derived from the
	// ASCII bytes of "schain", left-aligned and zero-padded to 32 bytes — the same
	// byte pattern dexvm uses (dexvm/factory.go:31, ids.ID{'d','e','x','v','m'}).
	VMID = ids.ID{'s', 'c', 'h', 'a', 'i', 'n'}
)

Functions

This section is empty.

Types

type Block

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

Block is an S-Chain block. It wraps the deterministic ProcessBlock result and implements chain.Block. It carries only the storage VM's needs: a header and the serialized PutManifest transactions — no cross-chain carried fills (the dexvm wire-format complication a storage VM does not have).

func (*Block) Accept

func (b *Block) Accept(ctx context.Context) error

Accept marks the block accepted and commits its state batch in ONE atomic write (the single commit point — dexvm/block.go:159). After this returns, the block's manifests are durable and GetManifest observes them.

func (*Block) Bytes

func (b *Block) Bytes() []byte

Bytes serializes the block. Wire format:

height[8] | timestamp[8] | parentID[32] | stateRoot[32] |
txCount[4] | txCount × ( txLen[4] | txBytes )

The txCount prefix makes the transactions self-delimiting. stateRoot is the proposer's claimed manifest state root, carried in the header so the block id (sha256 of these bytes) commits to it — a peer cannot swap the claimed root or a manifest while keeping the same id, and Verify rejects a claimed root that does not match the root recomputed from the applied txs.

func (*Block) Height

func (b *Block) Height() uint64

func (*Block) ID

func (b *Block) ID() ids.ID

func (*Block) Parent

func (b *Block) Parent() ids.ID

func (*Block) ParentID

func (b *Block) ParentID() ids.ID

func (*Block) Reject

func (b *Block) Reject(ctx context.Context) error

Reject discards the block's staged version-layer changes (dexvm/block.go:175).

func (*Block) Status

func (b *Block) Status() uint8

func (*Block) Timestamp

func (b *Block) Timestamp() time.Time

func (*Block) Verify

func (b *Block) Verify(ctx context.Context) error

Verify processes the block deterministically against the version layer, then enforces the manifest STATE ROOT: it recomputes the root from the txs it just applied and rejects the block if that computed root does not match the root the proposer claimed in the header. This is the multi-validator safety gate — a proposer (or a corrupted replica) whose post-apply manifest state diverges from what an honest validator computes cannot get its block accepted, because the claimed root (committed by the block id) and the recomputed root disagree. Verify performs NO external I/O on any node (mirror of dexvm/block.go:141); the manifest writes land in the in-memory version layer and become durable only at Accept.

type BlockResult

type BlockResult struct {
	BlockHeight uint64
	Timestamp   time.Time

	// StateRoot is the deterministic commitment over the manifest keyspace AFTER
	// this block's writes are staged, folded with the block's consensus binding
	// (blockHash + height). It travels in the block header and Block.Verify
	// recomputes it on every validator and rejects a block whose claimed root
	// does not match — the multi-validator safety gate M0 omitted.
	StateRoot ids.ID
	// contains filtered or unexported fields
}

BlockResult is the deterministic result of processing one block. For the storage VM the per-block output is simply the height/time/blockHash binding — the manifest mutations are staged directly into the version layer by ProcessBlock and committed at Accept. There is no cross-chain leg to carry.

type ChainVM

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

ChainVM wraps the functional storage VM to implement chain.ChainVM — the interface the chains manager drives. It owns the in-memory block index, mempool, and last-accepted pointers; the inner VM owns state + commit. This is the dexvm/chainvm.go boilerplate, stripped of the DEX fee gate and DAG hooks the storage VM does not need.

func NewChainVM

func NewChainVM(logger log.Logger) *ChainVM

NewChainVM constructs a ChainVM wrapping a fresh inner storage VM.

func (*ChainVM) BuildBlock

func (cvm *ChainVM) BuildBlock(ctx context.Context) (chain.Block, error)

BuildBlock drains the mempool into a new block on top of the preferred tip. The proposer chooses the block time (wall clock, clamped non-decreasing) and carries it in the bytes — the consensus-agreement point. The block id is the hash of the serialized bytes, so it commits to every drained transaction.

func (*ChainVM) Connected

func (cvm *ChainVM) Connected(ctx context.Context, nodeID ids.NodeID, v *version.Application) error

Connected is a no-op for M0 (no peer-version tracking needed).

func (*ChainVM) Disconnected

func (cvm *ChainVM) Disconnected(ctx context.Context, nodeID ids.NodeID) error

Disconnected is a no-op for M0.

func (*ChainVM) GetBlock

func (cvm *ChainVM) GetBlock(ctx context.Context, blkID ids.ID) (chain.Block, error)

GetBlock returns a block by id.

func (*ChainVM) GetBlockIDAtHeight

func (cvm *ChainVM) GetBlockIDAtHeight(ctx context.Context, height uint64) (ids.ID, error)

GetBlockIDAtHeight returns the accepted block id at a height.

func (*ChainVM) GetInnerVM

func (cvm *ChainVM) GetInnerVM() *VM

GetInnerVM exposes the inner VM for direct reads (e.g. GetManifest).

func (*ChainVM) HealthCheck

func (cvm *ChainVM) HealthCheck(ctx context.Context) (chain.HealthResult, error)

HealthCheck delegates to the inner VM.

func (*ChainVM) Initialize

func (cvm *ChainVM) Initialize(ctx context.Context, vmInit vmcore.Init) error

Initialize wires the inner VM and seeds the genesis block.

func (*ChainVM) LastAccepted

func (cvm *ChainVM) LastAccepted(ctx context.Context) (ids.ID, error)

LastAccepted returns the last accepted block id.

func (*ChainVM) NewHTTPHandler

func (cvm *ChainVM) NewHTTPHandler(ctx context.Context) (http.Handler, error)

NewHTTPHandler assembles the inner VM's handlers behind one mux.

func (*ChainVM) ParseBlock

func (cvm *ChainVM) ParseBlock(ctx context.Context, data []byte) (chain.Block, error)

ParseBlock parses a block from bytes, deduplicating against the index.

func (*ChainVM) SetPreference

func (cvm *ChainVM) SetPreference(ctx context.Context, blkID ids.ID) error

SetPreference sets the tip new blocks build on.

func (*ChainVM) SetState

func (cvm *ChainVM) SetState(ctx context.Context, stateNum uint32) error

SetState delegates to the inner VM.

func (*ChainVM) Shutdown

func (cvm *ChainVM) Shutdown(ctx context.Context) error

Shutdown delegates to the inner VM.

func (*ChainVM) SubmitTx

func (cvm *ChainVM) SubmitTx(tx []byte) error

SubmitTx admits a transaction to the mempool and notifies the engine to build a block. This is the canonical user-mempool entry. The bytes are validated (parse + Verify) before they touch the pending pool, so a malformed manifest never enters a block.

func (*ChainVM) Version

func (cvm *ChainVM) Version(ctx context.Context) (string, error)

Version delegates to the inner VM.

func (*ChainVM) WaitForEvent

func (cvm *ChainVM) WaitForEvent(ctx context.Context) (vmcore.Message, error)

WaitForEvent blocks until an event should trigger block building. M0 triggers builds via SubmitTx -> PendingTxs on toEngine, so this simply parks until the context is cancelled (mirror of dexvm/chainvm.go:408).

type Factory

type Factory struct{}

Factory creates new S-Chain VM instances for the chains manager.

func (*Factory) New

func (f *Factory) New(logger log.Logger) (interface{}, error)

New implements vms.Factory. It returns a ChainVM (which implements chain.ChainVM) for the chains manager to drive. Unlike dexvm, the storage VM allocates no GPU session — there is no latency-critical compute on its hot path; manifest commits are pure database writes.

type Status

type Status uint8

Status represents block status.

const (
	StatusUnknown Status = iota
	StatusProcessing
	StatusAccepted
	StatusRejected
)

type VM

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

VM is the inner functional storage VM. It holds the dual-DB layering and the typed manifest state; the chain.ChainVM wrapper (ChainVM) drives it.

func (*VM) CreateHandlers

func (vm *VM) CreateHandlers(ctx context.Context) (map[string]http.Handler, error)

CreateHandlers returns the VM's HTTP handlers. M0 exposes none (the VM contract + commit discipline is the deliverable; the S3 API surface is M1+).

func (*VM) GetBlockHeight

func (vm *VM) GetBlockHeight() uint64

GetBlockHeight returns the current block height.

func (*VM) GetLastBlockTime

func (vm *VM) GetLastBlockTime() time.Time

GetLastBlockTime returns the timestamp of the last processed block.

func (*VM) GetManifest

func (vm *VM) GetManifest(bucket, object string) (state.Manifest, bool, error)

GetManifest returns a committed manifest for (bucket, object). Reads go through the version layer, so this observes only state already committed by an accepted block (the in-memory staging from an unaccepted block is the proposer's transient view, not durable). The M0 proof asserts a manifest is visible here ONLY after Accept.

func (*VM) HealthCheck

func (vm *VM) HealthCheck(ctx context.Context) (chain.HealthResult, error)

HealthCheck reports the VM healthy once initialized.

func (*VM) Initialize

func (vm *VM) Initialize(ctx context.Context, vmInit vmcore.Init) error

Initialize sets up the VM with the consensus runtime, database, and channels. It establishes the dual-DB layering (baseDB durable, db versiondb) the commit discipline depends on — the exact wiring of dexvm/vm.go:311-321.

func (*VM) ProcessBlock

func (vm *VM) ProcessBlock(ctx context.Context, blockHeight uint64, blockTime time.Time, blockTxs [][]byte) (*BlockResult, error)

ProcessBlock deterministically applies a block's transactions to the version layer. It performs NO external I/O — the same inputs produce identical state on every node, so Verify is a pure function (mirror of dexvm/vm.go:542). The manifest writes land in vm.db's in-memory layer and become durable only when acceptBlock commits the batch.

func (*VM) SetState

func (vm *VM) SetState(ctx context.Context, stateNum uint32) error

SetState is a no-op for M0 (no bootstrap state machine to drive).

func (*VM) Shutdown

func (vm *VM) Shutdown(ctx context.Context) error

Shutdown closes the database.

func (*VM) Version

func (vm *VM) Version(ctx context.Context) (string, error)

Version returns the VM version string.

Directories

Path Synopsis
Package object wires the S3 OBJECT path to the S-Chain storage VM, proving the on-chain-metadata / off-chain-blob split end to end:
Package object wires the S3 OBJECT path to the S-Chain storage VM, proving the on-chain-metadata / off-chain-blob split end to end:
Package pinning is the deterministic single-writer assignment for the S-Chain storage VM.
Package pinning is the deterministic single-writer assignment for the S-Chain storage VM.
Package state manages persistent state for the S-Chain — the Lux storage VM.
Package state manages persistent state for the S-Chain — the Lux storage VM.
Package txs defines the transaction surface for the S-Chain — the Lux STORAGE VM.
Package txs defines the transaction surface for the S-Chain — the Lux STORAGE VM.

Jump to

Keyboard shortcuts

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