Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions .cargo/config.toml

This file was deleted.

12 changes: 10 additions & 2 deletions .github/actions/setup-tools/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ inputs:
rust-version:
description: 'Rust version to install (if Rust is setup)'
required: false
default: '1.86'
# Keep in step with the release container (rust:1.90-trixie in
# build.yml); the workspace uses post-1.86 std APIs.
default: '1.90'
foundry-version:
description: 'Foundry version to install'
required: false
Expand Down Expand Up @@ -36,7 +38,7 @@ runs:
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
if: ${{ inputs.setup-rust == 'true' }}
with:
components: rustfmt
components: rustfmt,clippy
target: ${{ inputs.target }}
toolchain: ${{ inputs.rust-version }}
cache-on-failure: false
Expand All @@ -55,3 +57,9 @@ runs:

- name: Install just
uses: extractions/setup-just@53165ef7e734c5c07cb06b3c8e7b647c5aa16db3 # v4.0.0
with:
# Pinned like rust and foundry above: a floating "latest"
# upgrades CI's toolchain silently mid-week (1.56 -> 1.57
# landed between two runs of this workflow and muddied a
# two-day CI hunt). Bump deliberately.
just-version: "1.57.0"
81 changes: 72 additions & 9 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
name: Build
# Push covers the long-lived branches and release tags; pull_request
# covers everything else, including forks (which get no CI at all
# under a bare push trigger). The concurrency group below dedupes.
on:
push:
branches:
- main
- "next/*"
tags:
- "v*"
pull_request:
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
Expand Down Expand Up @@ -95,10 +104,40 @@ jobs:
working-directory: ./test/programs/
run: |
just build-honeypot-snapshot
- name: Build echo
working-directory: ./test/programs/
run: |
just build-echo
- name: Test prt-rollups
timeout-minutes: 20
run: |
just test-rollups-honeypot-ci
# B2 batched sibling: SIGKILL mid advance batch, the resumed run
# must re-execute the batch and settle identically to the oracle.
# Cheap (no dispute), and the only e2e that puts a full
# multi-record batch under the kill (the harness default is
# gap 2, small batches).
- name: Test batched catch-up kill
timeout-minutes: 15
run: |
just test-rollups-kill-ci
# B1 chaos loop (docs/plans/characterization.md): the dispute must
# survive SIGKILL/respawn fire. Fixed seed: CI is the regression
# net; seed exploration stays in local runs.
- name: Test chaos
timeout-minutes: 15
env:
CHAOS_SEED: "1"
run: |
just test-rollups-chaos
# The state-transition coverage suite: every on-chain STF shape
# driven through a real dispute (docs/test-harness.md coverage
# matrix). The battery's most valuable net; it rotted once while
# living outside CI.
- name: Test stf_all
timeout-minutes: 60
run: |
just test-rollups-honeypot-stf
- name: Show failing log
if: failure()
run: |
Expand Down Expand Up @@ -126,34 +165,58 @@ jobs:
build-essential git wget \
libslirp-dev \
libclang-dev \
liblua5.4-dev lua5.4 \
liblua5.4-dev lua5.4 lua-check \
xxd jq sqlite3 libc6 clang libarchive13

wget -O xgenext2fs.deb https://github.com/cartesi/genext2fs/releases/download/v${XGENEXT2_VERSION}/xgenext2fs_${ARCH}.deb
sudo apt-get install -y ./xgenext2fs.deb
rm ./xgenext2fs.deb
xgenext2fs --version

# The from-source emulator build dominates this job. The tree is
# make-based and the diff apply detects an already-patched tree,
# so on a cache hit the same recipes below no-op; on an emulator
# bump the key changes and the from-source path runs for real.
- name: Emulator cache key
id: emulator-key
run: echo "sha=$(git rev-parse HEAD:machine/emulator)" >> "$GITHUB_OUTPUT"

- name: Cache emulator build
uses: actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
with:
path: machine/emulator
key: emulator-build-${{ runner.os }}-${{ steps.emulator-key.outputs.sha }}

# The version and diff hash live in the justfile recipe; CI must
# not carry its own copy of either. Dependency form (`setup`)
# deliberately: chaining recipes on one CLI feeds the NEXT
# recipe name into a parameterized recipe's arguments (just's
# grammar) - `apply-generated-files-diff build-emulator` once
# downloaded release "build-emulator" and 404ed silently.
- name: Install Cartesi Machine
working-directory: ./machine/emulator
run: |
make bundle-boost
wget -O add-generated-files.diff https://github.com/cartesi/machine-emulator/releases/download/v0.20.0/add-generated-files.diff
echo "d9c2afcefc2759e7cd37bbedc83d54c81515f0fddb671103b489b8789aee33bb add-generated-files.diff" | sha256sum -c
git apply add-generated-files.diff
rm add-generated-files.diff
make
sudo make install
just setup
sudo make -C machine/emulator install

- name: Setup env
run: |
just setup-local

# The same targets `just check` runs locally, one step each so a
# failure is legible in the Actions UI.
- name: Rust fmt and check
run: |
just check-fmt-rust-workspace
just check-rust-workspace

- name: Clippy
run: |
just clippy-rust-workspace

- name: Lua lint
run: |
just lint-lua

- name: Rust build
run: |
just build
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ node_modules
**/snapshots/
**/compute_data/
**/rollups_data/
**/_machine_scratch*/
soljson-latest.js
140 changes: 140 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
# Dave - agent context

Dave is Cartesi's permissionless, interactive fraud-proof system, currently
implemented on top of the Permissionless Refereed Tournaments (PRT) algorithm.
This repository holds the on-chain dispute contracts, two off-chain clients
(a prototype Rust node and a Lua testing node), the Cartesi Machine
integration, and the test infrastructure that ties them together.

> The code is the source of truth. The papers, the comments, and these docs
> have drifted before and will drift again. Where they disagree, trust the
> code, and prefer verifying a claim over relying on any document's specifics.

## Repository map

```
prt/contracts/ Solidity dispute contracts - SECURITY-CRITICAL trust
boundary. Deep context in prt/contracts/AGENTS.md.
prt/client-lua/ PRT client in Lua. Testing node, sybil actor, and
executable reference for commitment construction.
prt/tests/ Lua-orchestrated end-to-end tests. Spawns the real Rust
node plus dishonest sybils against anvil.
prt/docs/ The original PRT paper (prt.pdf).
dave/docs/ The Dave paper (dave.pdf), a liveness improvement over
PRT. NOT what the current contracts implement.
cartesi-rollups/
contracts/ Rollups consensus contracts (DaveConsensus, app factory).
node/ The rollups node, a single crate: worker modules
synchronize through the storage module (the only
SQL surface); the dispute engine lives in the
engine/hero/tournament modules, and the shared
primitives (merkle, arithmetic, kms) are folded-in
modules, not separate crates.
machine/ Cartesi Machine: emulator + solidity-step submodules and
the Rust bindings that link against the emulator.
test/programs/ Machine images used by tests (echo, yield, honeypot).
docs/ The knowledge base. Start at docs/README.md.
```

## What matters where

- `prt/contracts/` is on-chain and trust-bearing: it decides which computation
result is canonical. Bugs there are consensus bugs. See
`prt/contracts/AGENTS.md` before touching anything.
- The node (`cartesi-rollups/node/`) is the honest
validator's sword. A node bug does not break the protocol, but it can
forfeit a dispute the honest party should have won: wrong commitments or
missed deadlines lose tournaments. Treat commitment construction and proof
generation as correctness-critical, not just liveness-critical.
- The Lua client and the Solidity state-transition tests double as
cross-implementation oracles for the Rust code. Tests compare their outputs;
keep all implementations in agreement.

## Where knowledge lives

- `docs/computation-hash.md` - how commitments are built: the meta-cycle
coordinate system, uarch spans, checkpoints, and revert. Read this before
touching anything under `cartesi-rollups/node/src/engine/` or
`cartesi-rollups/node/src/storage/rollups_machine.rs`.
- `docs/dimensioning.md` - the trust model (who may be adversarial) and
the worst-vs-average dimensioning rule with its reasoning. Read before
touching clocks, spans, timeouts, or tournament constants.
- `docs/epoch-lifecycle.md` - inputs, epochs, sealing, disputes, settlement.
- `docs/node-architecture.md` - the prototype node's threads, database, and
known technical debts.
- `docs/test-harness.md` - how the Lua e2e orchestration works and how to add
scenarios.
- `docs/glossary.md` - the project vocabulary (ustep, ureset, barch,
meta-cycle, dangling commitment, and the span-vs-mask naming trap).
- `docs/build-system.md` - how setup and builds work, and open design
questions (bindings generation, emulator dependency).

## Build and test

Requires: git, docker, just, GNU make, foundry, and for native runs a C++
toolchain, Lua 5.4, Rust, and the Cartesi Machine. See the root `README.md`
and `docs/build-system.md`.

```bash
just doctor # diagnose the checkout; every problem names its fix
just setup # one-time: submodules, deps, emulator build
just build # contracts + bindings + rust workspace
just check # THE pre-commit gate: fmt, lints, clippy, unit tests
just test-rust-workspace # rust unit tests
just test-smart-contracts # forge test suites (consensus + prt)
just test-rollups-echo # e2e: honest node, echo machine
just test-rollups-honeypot # e2e: full honeypot scenario suite
```

When something fails mysteriously, run `just doctor` before debugging: it
checks tools, submodules, bindings, machine images, and devnet artifacts,
and prints the fixing command for anything missing.

For long commands, prefer `just logged <file> <cmd...>`: it writes the
full output to the file and reports the TRUE exit code. Piping through
`tail`/`grep`/`head` reports the last pipe stage's status and has
laundered real failures into green output more than once.

At the end of a work session, run `just worktrees-sweep` (and
`just rollups-tests::sweep` after reading e2e results): session worktrees
accumulate regenerable bulk - build caches and e2e state - that outlives
their sessions by months. `just worktrees-report` shows the damage.

The Rust workspace does not build with plain `cargo` from a fresh clone: the
Solidity bindings are generated (not committed), so run `just bind` (or any
just cargo recipe) at least once. The emulator is linked from
`LIBCARTESI_PATH` when set (the nix devshell exports it); without it,
`cartesi-machine-sys` builds the `machine/emulator` submodule from source.

## Conventions

Comments and prose:

- Do not use unicode inside comment phrases and prose. Plain ASCII.
- Keep comments concise. Avoid redundant and excessive inline commentary.
- Comment the non-obvious, not the self-evident. Do not restate what the code
already expresses. Explain the why, edge cases, invariants, and subtle
behaviors that cannot be inferred from reading the code alone.

These apply to documentation files as well. When writing docs, prefer stating
invariants and reasons (stable) over restating code structure (volatile), and
mark uncertain claims as leads to verify rather than facts.

Code:

- Rust is formatted with `cargo fmt` (`just check-fmt-rust-workspace`).
- Solidity is formatted with `forge fmt` (run `just check-fmt` inside the
contracts directory you touched).
- Match the surrounding code's style and idiom; this is a multi-author
codebase with history.

## Current state (written 2026-07)

- `main` holds the released 2.x line; `next/3.0` is the base branch for the
next version. New work targets `next/3.0`.
- The Rust node is an acknowledged prototype. It works and passes the e2e
suites, but it is scheduled for an incremental rewrite (the "sling node").
Recon and characterization tests come first; avoid opportunistic
refactoring of node internals until that harness exists.
- An external security audit of `prt/contracts` is ongoing. Be conservative
with contract changes.
4 changes: 4 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
@AGENTS.md

Subsystem-specific context lives in nested files; the closest one to the code
you are editing wins. Currently: `prt/contracts/AGENTS.md`.
Loading