Skip to content

feat(cli): Add support to NVRAM - #519

Merged
brunomenezes merged 12 commits into
prerelease/v2-alphafrom
feat/cli-add-nvram-support
Oct 5, 2026
Merged

brunomenezes merged 12 commits into
prerelease/v2-alphafrom
feat/cli-add-nvram-support

Conversation

@brunomenezes

@brunomenezes brunomenezes commented Aug 18, 2026 •

Copy link
Copy Markdown
Member

Summary

Adds NVRAM support to the CLI, declared in cartesi.toml and translated into cartesi-machine's --nvram option. Rebased onto prerelease/v2-alpha, so the emulator 0.21.0 and rollups-node 2.0.0-alpha.13 groundwork from #529 is already in place — this PR no longer carries a merge blocker or a temporary commit.

An NVRAM is a raw range of bytes exposed to the guest as a /dev/uio* device. Unlike a flash drive it has no filesystem, no mount point and no page cache between the guest and the memory range, so writes are visible to the emulator immediately with no flush before snapshotting. That makes it the primitive for an application that wants a fixed region of bytes it can mmap() and persist across advance states.

Features

  • [nvrams] in cartesi.toml. Optional — a config without it emits no new flags and runs no new build steps. Each table needs size or filename (or both, which must agree exactly); sizes must be a multiple of 4Ki, at most 8 nvrams are supported, and labels cannot collide with drive labels since both share the DTB /aliases namespace. All validated at parse time, so a bad config fails before anything is built.

    [nvrams.input]
    size = "4Ki"              # pristine, zero-filled by cartesi-machine
    
    [nvrams.output]
    size = "4Ki"
    shared = true             # guest writes persist to .cartesi/output.raw
    user = "dapp"             # required for the application to write to it
    
    [nvrams.seed]
    filename = "./seed.raw"   # existing raw image; size defaults to the file size
  • Only the nvrams that need a backing image get built. A shared one is allocated zero-filled in .cartesi/; a filename one is copied there, leaving the source untouched. A pristine nvram produces no artifact at all, since the emulator fills the range itself.

  • The emulator version requirement is now enforced. feat(cli): cli changes to align with rollups-node [upcoming changes] #529 moved requiredVersion to ^0.21.0, but nothing read it at runtime and doctor never checked the emulator. build and shell now verify before booting and doctor reports it alongside the Docker checks, so a stale install gives cartesi-machine 0.20.0 found, but ^0.21.0 is required instead of a raw unrecognized option --nvram=... lua traceback. The check deliberately does not block when the version cannot be determined, since that also happens with Docker down or the binary missing.

Fixes

  • The version check ignored its forceDocker option, rebuilding the options object and dropping it, so it reported the host binary's version instead of the SDK image's. This is why the existing assertion in cartesi-machine.test.ts passed for anyone with a matching local install and failed in CI. The cwd it needs for the Docker volume mount was also unset.

Refactoring

  • Argument assembly extracted from bootMachine into a pure buildMachineArgs, so the generated flags are unit-testable without spawning a machine.
  • The version predicate extracted as assertSupported(found), separating the decision from the subprocess that discovers it — testable directly, with no module mocking.

Verification

Full suite — unit and integration — against the released 0.12.0-alpha.43 images with no environment overrides: 235 pass / 1 skip / 0 fail across 19 files. The base measures 184/1/0, so this adds 51 tests and keeps it green; the skip is pre-existing (docker.test.ts sqfs drive). tsc reports no errors under src/.

The nvram boot test runs rather than skips — it is gated on the emulator supporting --nvram, and alpha.43 does. It builds a throwaway application declaring a pristine input and a shared output, then asserts that only the nvrams needing an image get one, that the guest exposes one /dev/uio* per nvram, that labels resolve in cartesi.toml order, and that writemmap/readmmap round-trips and reaches the host's output.raw — the assertion that actually proves shared.

Version gate checked both ways: cartesi doctor reports ✔ Cartesi Machine 0.21.0, and a project pinned to sdk = "cartesi/sdk:0.12.0-alpha.41" (emulator 0.20.0) fails with UnsupportedVersionError rather than reaching the emulator.

@changeset-bot

changeset-bot Bot commented Aug 18, 2026 •

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 69fa431

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@cartesi/cli Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@brunomenezes brunomenezes moved this to 🧑‍💻 In Progress in Rollups Tooling Aug 18, 2026
@brunomenezes brunomenezes self-assigned this Aug 18, 2026
@github-actions

github-actions Bot commented Aug 18, 2026 •

Copy link
Copy Markdown
Contributor

Coverage Report

Status Category Percentage Covered / Total
🟢 Lines 98.24% (🎯 0%) 5137 / 5229
🔵 Statements 98.24% 5137 / 5229
🔵 Functions 94.44% 153 / 162
🔵 Branches 0% 0 / 0
📁 File Coverage (20 files)
File Lines Statements Functions Branches Uncovered Lines
apps/cli/src/builder/directory.ts 🟢 100% 🟢 100% 🟢 100% 🔴 0% -
apps/cli/src/builder/docker.ts 🟢 86.72% 🟢 86.72% 🟡 66.67% 🔴 0% 75-77, 79, 109-111, 169-178
apps/cli/src/builder/empty.ts 🟢 100% 🟢 100% 🟢 100% 🔴 0% -
apps/cli/src/builder/none.ts 🟢 100% 🟢 100% 🟢 100% 🔴 0% -
apps/cli/src/builder/nvram.ts 🟢 96.88% 🟢 96.88% 🟢 100% 🔴 0% 27
apps/cli/src/builder/tar.ts 🟢 100% 🟢 100% 🟢 100% 🔴 0% -
apps/cli/src/compose/builder.ts 🟢 99.79% 🟢 99.79% 🟢 100% 🔴 0% 228
apps/cli/src/compose/common.ts 🟢 100% 🟢 100% 🟢 100% 🔴 0% -
apps/cli/src/compose/node.ts 🟢 99.24% 🟢 99.24% 🟢 100% 🔴 0% 106
apps/cli/src/config.ts 🟢 95.12% 🟢 95.12% 🟢 96.15% 🔴 0% 78-79, 298, 307, 316, 410, ...
apps/cli/src/contracts.ts 🟢 100% 🟢 100% 🟢 100% 🔴 0% -
...rc/errors/ForkChainValidationError.ts 🟢 100% 🟢 100% 🟢 100% 🔴 0% -
...c/errors/UnsupportedForkChainError.ts 🟢 100% 🟢 100% 🟢 100% 🔴 0% -
...c/exec/cartesi-machine-stored-hash.ts 🟢 92.86% 🟢 92.86% 🟢 100% 🔴 0% 36-37
apps/cli/src/exec/cartesi-machine.ts 🟢 89.19% 🟢 89.19% 🟢 100% 🔴 0% 27-29, 53
apps/cli/src/exec/genext2fs.ts 🟢 96.92% 🟢 96.92% 🟢 100% 🔴 0% 87-88
apps/cli/src/exec/index.ts 🟢 100% 🟢 100% 🟢 100% 🔴 0% -
apps/cli/src/exec/mksquashfs.ts 🟢 91.53% 🟢 91.53% 🟢 100% 🔴 0% 70-74
apps/cli/src/exec/util.ts 🟢 85.11% 🟢 85.11% 🟡 66.67% 🔴 0% 24-28, 68-69
apps/cli/src/machine.ts 🟢 82.48% 🟢 82.48% 🟡 70% 🔴 0% 19, 22, 25, 81-82, 88, 101,...

@brunomenezes brunomenezes changed the title feat(cli): Support nvrams in cartesi.toml feat(cli): Add support to NVRAM Aug 18, 2026
@brunomenezes
brunomenezes force-pushed the feat/cli-add-nvram-support branch from 391697a to 9a7432d Compare August 18, 2026 18:29
@tuler
tuler force-pushed the refactor/sdk-update-anvil-state-source branch from edd91c9 to 0a66b6f Compare September 2, 2026 20:57
@brunomenezes
brunomenezes force-pushed the feat/cli-add-nvram-support branch from 9a7432d to 2d4fe71 Compare October 3, 2026 09:18
Base automatically changed from refactor/sdk-update-anvil-state-source to prerelease/v2-alpha October 3, 2026 12:33
@brunomenezes
brunomenezes force-pushed the feat/cli-add-nvram-support branch from 2d4fe71 to af62c9f Compare October 5, 2026 19:38
@brunomenezes
brunomenezes marked this pull request as ready for review October 5, 2026 19:44
@brunomenezes
brunomenezes merged commit 4a16187 into prerelease/v2-alpha Oct 5, 2026
2 of 4 checks passed
@brunomenezes
brunomenezes deleted the feat/cli-add-nvram-support branch October 5, 2026 20:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

Status: 📦 Done

Development

Successfully merging this pull request may close these issues.

2 participants