state

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: 8 Imported by: 0

Documentation

Overview

Package state manages persistent state for the S-Chain — the Lux storage VM.

M0 persists exactly two things over the chain's database namespace:

  1. MANIFESTS — the (bucket, object) -> {fileIds, size, etag} mapping that records which content blobs make up an object.
  2. LAST-BLOCK pointer — the last-accepted block id + height, the recovery anchor.

Every accessor reads/writes through the supplied database.Database, which the VM hands in as a *versiondb.Database (the per-block in-memory version layer). A Put therefore stages into the version layer during block processing and becomes durable ONLY when the VM commits the batch at Accept — the exact commit discipline dexvm/state/state.go follows. This package never imports the zapdb engine directly; it speaks only the luxfi/database interface, so the VM is free to swap the backing store.

Index

Constants

This section is empty.

Variables

View Source
var (
	// ErrStateCorrupted is returned when a stored value cannot be decoded into
	// its expected shape — a corrupt record must never be silently reinterpreted.
	ErrStateCorrupted = errors.New("state corrupted")
)

Functions

This section is empty.

Types

type Manifest

type Manifest struct {
	FileIDs []string `json:"fileIds"`
	Size    int64    `json:"size"`
	ETag    string   `json:"etag"`
}

Manifest is the committed content manifest for one object: the file blobs that compose it plus the object-level metadata an S3 HEAD returns. It is encoded as a deterministic JSON body (no maps, declaration-order fields), the same self-describing, protobuf-free style dexvm uses for its structured values.

type State

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

State manages the S-Chain's persistent state over the version layer `db`.

func New

func New(db database.Database) *State

New creates a state manager over db — the per-block version layer the VM commits atomically at Accept. Mirrors dexstate.New (dexvm/state/state.go:96), minus the durable receipt side-channel the storage VM does not need in M0.

func (*State) GetLastBlock

func (s *State) GetLastBlock() (ids.ID, uint64)

GetLastBlock returns the last accepted block id and height.

func (*State) GetManifest

func (s *State) GetManifest(bucket, object string) (m Manifest, found bool, err error)

GetManifest returns the manifest for (bucket, object). found is false when no manifest exists. Reads through the version layer, so it observes a manifest staged in this block before commit (the in-flight view) and the durable store after commit — identical to dexvm's versiondb-backed reads.

func (*State) Initialize

func (s *State) Initialize() error

Initialize loads the last-accepted block pointer from the database.

func (*State) PutManifest

func (s *State) PutManifest(bucket, object string, m Manifest) error

PutManifest stages a manifest into the version layer. It becomes durable only when the VM commits the block's batch at Accept — before that, a GetManifest on a freshly-constructed reader over the base DB does not see it. This is the versiondb/CommitBatch discipline the M0 proof asserts.

func (*State) Root

func (s *State) Root() (ids.ID, error)

Root returns a deterministic SHA-256 commitment over the COMMITTED manifest keyspace: every manifest/<bucket>/<object> -> {fileIds,size,etag} entry the chain holds after this block's writes are staged. It is the value the block header binds, so two validators whose manifest state actually diverges (a different object set, a changed etag/size/fileIds for the same object) ALWAYS produce different roots — divergence can never hide behind a matching block hash. This is the manifest-VM analog of dexvm's State.StateHash (dexvm/state/ state.go:395), narrowed to the storage VM's one keyspace.

The walk uses the zapdb prefix iterator NewIteratorWithStartAndPrefix(nil, prefixManifest), so it reads through the versiondb (this block's staged in-memory writes merged over the durable base, deleted keys dropped) and only the manifest keyspace — the last-block pointer is consensus binding folded separately into the header via blockHash/height, NOT object state, so it is excluded here exactly as dexvm excludes its proposer-local receipt prefix.

Keys come out in lexicographic order, so the digest is independent of write history and identical across nodes. Each entry is folded length-prefixed (len(key)||key||len(value)||value) so no two distinct (key,value) splits can collide by concatenation.

func (*State) SetLastBlock

func (s *State) SetLastBlock(blockID ids.ID, height uint64) error

SetLastBlock records the last accepted block id + height (32+8 bytes).

Jump to

Keyboard shortcuts

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