Skip to content Search Apps Documentation Source Content File Folder Download Copy Actions State String Boolean Number Struct Map Slice Pointer Function Closure Reference Nil Package Type Interface Unknown

Community realm. Read the code first. Community realm, deployed by its author. Read the code before you interact or send coins.

/p/nym-moultest123/x/vm/vmkit/v0

Directory · 9 Files
README.md Open

p/moul/x/vm/vmkit

The host ABI shared by every guest virtual machine that runs inside a gno realm: a stepping contract with an explicit fuel budget, a capability-scoped Host, and a snapshot format that lets a guest program outlive the transaction that started it.

A guest VM implements Machine. Everything else here is the machinery a VM should not have to write twice: the Meter, the canonical Writer/Reader snapshots are built from, an in-memory TestHost, and the avl-backed Store a realm keeps its instances in.

First consumer: p/moul/x/vm/bf. Live demo: r/moul/x/vm/bfdemo.

1type Machine interface {
2	Step(h Host, fuel int64) (used int64, status Status)
3	Snapshot() []byte
4	Restore(b []byte) error
5}

Status is one of Running, Halted, Trapped, OutOfFuel.

What the ABI is for

Fuel is the interface, not the backstop. Running out of fuel yields OutOfFuel plus a machine that can be snapshotted, never a panic. Gas still bounds the transaction; it is just not the thing a guest program is written against.

Continuations. Snapshot and Restore mean a program runs across blocks. The realm stores the bytes, the next caller pays for the next slice. Gno realm code cannot pause itself; a guest can. The property that makes this real is tested rather than asserted: five slices of one fuel unit must produce exactly what one slice of five produces, for every program in bf's corpus.

Capabilities, not ambient authority. A guest gets exactly the Host it was handed. Send returns ErrNotGranted unless the deploying realm funded a budget, storage is scoped to the instance, and nothing is looked up. Gno itself has ambient authority through the realm frame, so the guest is where the capability-secure version can actually be tried.

Meter is not a hot-path type

Meter exists for the API boundary: compute a slice budget, charge it once, report what was used. Calling Meter.Charge once per guest instruction was measured at +86% on top of an entire interpreter dispatch loop, and more than tripled its allocation count. A machine should count fuel in a local and settle up with the caller. The numbers are in bf's README.

Charge spends nothing when the budget cannot cover the request, so a machine that stops for lack of fuel is exactly at the instruction it could not pay for, and resuming re-executes that instruction and no other.

The snapshot codec

Writer and Reader are fixed-width big-endian with length-prefixed bytes, so the encoding is canonical: the same machine state always produces the same bytes, on every node. A snapshot is consensus state, so two nodes encoding it differently is a fork, and a short read is a hard error rather than a zero value.

Machines are not required to use it, but a machine that invents its own layout owes the zoo an explanation: the cross-VM snapshot cost comparison only means something when the encodings match.

Instance and Store

Instance is one guest program as a realm stores it: code, snapshot between slices, status, and the fuel accounting that survives the transaction. It holds bytes rather than a Machine on purpose, which is what makes the storage cost of a paused program measurable.

Instance.Run folds one slice back into the instance and leaves it untouched when Restore fails, so a snapshot that cannot be decoded costs the caller gas but never corrupts the stored program.


Part of moul/gno-contracts — moul's versioned gno.land contracts. See the repository for the full catalog, build/test tooling, and usage.

Dependency graph:

gno.land/p/nym-moultest123/x/vm/vmkit/v0 dependency graph

🧪 Highly experimental — potentially vibe-coded. Not audited; may break, change, or be removed at any time. Do not use with anything of value. Full disclaimer: DISCLAIMER.