Operator CLI
lattice is the declarative front door for one host. It reads one
lattice.json, owns no resident state, and reconciles one lattice-node
process that hosts the configured Nexus-rooted tree.
Every command accepts --root <directory>. The current directory is the
default.
Topology
Section titled “Topology”{ "listen": 4001, "rpc": 8080, "webSocket": 4002, "peers": ["<public-key>@node.example:4001"], "externalAddress": "192.0.2.10", "publicRead": 8081, "publicReadRate": 25, "publicReadExpensiveRate": 1, "publicReadMaxRate": 200, "publicReadURL": "https://reads.example.org", "publicSubmit": false, "hostedChains": [ "Nexus/Alpha", "Nexus/Alpha/Beta" ], "mine": { "worker": "cpu", "workers": 2, "batchSize": 2000000, "recipients": { "Nexus": "<address>", "Nexus/Alpha": "<address>", "Nexus/Alpha/Beta": "<address>" }, "minBlockIntervalSeconds": 10 }}This is intentionally one schema:
listen,rpc, public-read policy, and identity apply once to the process;peersis a list per chain, keyed by absolute path; an array is Nexus’s list (see “Configured peers” inoperations.md);hostedChainslists child paths parent before child;- mining maps are keyed by hosted absolute path;
- ports must be nonzero and unique, except that
webSocketmay be 0, which turns the browser listener off (see “Network surfaces” inoperations.md); - rates must be finite and nonnegative;
blockBodies, when set, isallornoneand is passed as--block-bodies(see “What a node keeps” inoperations.md);state, when set, isall,tipornoneand is passed as--state(same section);finalityWindow, when set, is a number of blocks and is passed as--finality-window Nfor every hosted chain; absent or 0 is off (see Node-local finality);finalityWindows, when set, maps a chain path to blocks ({"Nexus/Alpha": 500}) over that default and is passed as--finality-window path=N; 0 turns it off for that chain;announceLifetime, when set, is 1 to 86400 and is passed as--announce-lifetime(see “Discovery and peer health” inoperations.md);publicReadURL, when set, is an absolutehttps://(orhttp://) URL with a host and no credentials, query or fragment; it is passed as--public-read-urland declared for every hosted level (see Listing a chain on an explorer);publicReadFetches, when set, is nonnegative and is passed as--public-read-fetches: how many Volumes the public listener reads from peers at once for readers when the node does not hold them (seeGET /volumes/:cid);0serves only what the node holds;publicSubmit, when true, passes--public-submitand requirespublicRead: the public listener also acceptsPOST /transactions(see Running a public submit endpoint); absent or false is off;- unknown paths in mining policy are rejected.
Lifecycle
Section titled “Lifecycle”| Command | Effect |
|---|---|
lattice init |
Create lattice.json and the process identity, refusing to overwrite a topology. |
lattice up |
Start the one node process in the background. Restart it when the configured hosted path set changed. |
lattice up --foreground |
Supervise the node for container or init-system use. |
lattice status |
Read every hosted level from the one loopback RPC. |
lattice down |
Stop the node process under the spawn lock. |
lattice wipe |
Remove the complete stopped tree storage. Preserve identity, specs, and topology. |
lattice identity |
Print the process public key and peer string. |
Examples:
lattice init --root /var/lib/latticelattice up --root /var/lib/latticelattice status --root /var/lib/latticelattice down --root /var/lib/latticeThe PID file names the executable as well as the PID, so a recycled PID is not
signalled. Start, stop, restart, child creation, and wipe share one spawn lock.
Storage also has its own writer lock; wipe refuses if any node still owns it.
Child chains
Section titled “Child chains”lattice child create Nexus/Alpha \ --root /var/lib/lattice \ --block-time 10000 \ --reward 1000 \ --premine 0Or provide a complete ChainSpec JSON:
lattice child create Nexus/Alpha \ --root /var/lib/lattice \ --spec alpha-spec.jsonA spec names each WASM policy module by CID in wasmPolicies. Give the file
for every module it names:
lattice child create Nexus/Alpha \ --root /var/lib/lattice \ --spec alpha-spec.json \ --policy-module transfer-rules.wasm \ --policy-module action-rules.wasmEach file is matched to the spec by its CID and checked against the policy ABI; creation is refused if a file is one the spec does not name, or a named module has no file. The modules are kept beside the spec, and the node stores them at start, so it can store and serve the genesis it mines.
A spec with a premine needs the account the genesis pays it to:
lattice child create Nexus/Alpha \ --root /var/lib/lattice \ --spec alpha-spec.json \ --premine-to <address>premine counts blocks of the reward schedule; the genesis pays their rewards
to that account in one unsigned credit, as Nexus’s genesis pays its own, and
genesis validation bounds the credit by the premine. Creation is refused for a
premine with no account, an account that is not an address, or a genesis one of
the spec’s transaction policies refuses. The account is kept beside the spec
and passed to the node as --premine-to <path>=<address>, which the node checks
the same way at start.
A chain can also start with state its creator writes, such as names the creator holds from the first block, as signed transactions the genesis carries after its premine:
lattice child create Nexus/Alpha \ --root /var/lib/lattice \ --spec alpha-spec.json \ --genesis-transactions genesis.jsonThe file is a JSON array of what POST /transactions takes. Genesis validation
does not check signatures, so creation does: each transaction must be signed by
exactly its signers, be for this chain, carry no coin, deposit, receipt or
withdrawal actions (a genesis pays only its premine), and pass the spec’s
transaction policies; with the premine they must fit one block. The file is
kept beside the spec and passed to the node as
--genesis-transactions <path>=<file>, which the node checks the same way at
start. A signer’s later transactions continue from the nonces its genesis
transactions used.
Creation writes one immutable spec and adds the path to hostedChains. The
node builds the genesis candidate from that spec when the parent has an
executed state it can commit, and ordinary merged mining secures it. There is
no child-deploy command or parent authorization transaction.
For a nested child, create the parent first. Its genesis is not eligible until the parent has executed a block. Give a chain positive rewards before relying on it as a parent; a reward-free, transaction-free chain never changes state.
Mining
Section titled “Mining”| Command | Effect |
|---|---|
lattice mine start |
Start the background coordinator loop. |
lattice mine status |
Show its PID and configured recipients. |
lattice mine stop |
Finish or bound the active round, then stop. |
mine.worker is cpu for the bundled worker or an executable path implementing
the worker contract. mine.recipients controls each chain’s reward and fee
recipient; an omitted path burns that payout. mine.minWork is a local search
filter, not a committed consensus target. mine.minBlockIntervalSeconds is a
floor on template spacing and releases itself when rounds run longer.
The mining loop probes the node for the template expiry and places a deadline around each coordinator process group. A timeout is logged loudly and the next round retries.
Spending keys and transactions
Section titled “Spending keys and transactions”lattice key generate --out ./wallet.jsonKey files are created mode 0600, and transaction commands refuse a
group/other-readable key.
lattice tx send \ --root /var/lib/lattice \ --chain Nexus/Alpha \ --key ./wallet.json \ --to <address> \ --amount 25 \ --fee 1tx deposit, tx receipt, and tx withdraw expose the three cross-level
exchange actions. All submissions use the one RPC listener and carry their
absolute chain path. The CLI rejects a path this host does not serve; the node
also returns 404 for an unhosted path.
systemd
Section titled “systemd”Generate foreground units from the configured topology:
lattice emit-systemd --root /var/lib/lattice \ > /etc/systemd/system/lattice.generated.unitsThe checked-in examples are deploy/lattice-node.service
and deploy/lattice-mining-coordinator.service.
The coordinator unit requires a nonempty RECIPIENT_ARGS in
/etc/lattice/mining.env so production mining cannot silently burn all
rewards.
Layout
Section titled “Layout”<root>/ lattice.json identity/Nexus.key specs/Nexus%2FAlpha.json chains/Nexus/ state.db volumes.db volume-bundles.db storage.lock run/ log/There is no per-chain process, port, key, or child state.db. The path in
specs/ identifies a level; runtime facts for every level share the one tree
journal.
Source: lattice-node/docs/operator-cli.md at 9abd15b1bb05