Skip to content
Draft
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
17 changes: 16 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ jobs:
- name: Verify toolchain pin alignment
run: bash scripts/verify-toolchain-pins.sh

# libclang-dev is what bindgen needs; several crates run it, c-app-engine among them
- name: Install system dependencies
run: |
sudo apt-get update
Expand All @@ -27,7 +28,8 @@ jobs:
libfaketime \
lua5.4 \
liblua5.4-dev \
libslirp-dev
libslirp-dev \
libclang-dev

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
Expand Down Expand Up @@ -62,6 +64,19 @@ jobs:
timeout-minutes: 15
run: cargo test --workspace --all-targets --all-features --locked

# The rest of the job only builds the C seam the way an in-workspace crate uses it. This is
# the other way, the one an application outside this repository takes: hand the engine over
# as an archive and link it through the three binding variables. c-wallet-engine's staticlib
# stands in for that archive.
- name: C application archive path
run: |
cargo build --locked -p c-wallet-engine
APPLICATION_ENGINE_LIB="$PWD/target/debug/libc_wallet_engine.a" \
APPLICATION_ENGINE_HEADER="$PWD/examples/c-app-engine/include/application-engine.h" \
APPLICATION_ENGINE_METHOD_PAYLOAD_LIMIT=53 \
cargo build --locked -p c-app-sequencer
./target/debug/c-app-sequencer --help > /dev/null

canonical-guest:
runs-on: ubuntu-latest
needs: rust
Expand Down
4 changes: 4 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,10 @@ Top-level layout follows the system's data flow. Each sequencer module correspon
- `sequencer-core/` — shared domain types (`Application`, `SignedUserOp`, `SequencedL2Tx`, `Batch`, `Frame`).
- `examples/app-core/` — placeholder wallet app implementing the `Application` trait.
- `examples/wallet-sequencer/` — binary crate: wallet app + sequencer library. The model for what an app author builds (their `Application` impl ≙ `app-core`; their binary crate ≙ this).
- `examples/c-app-engine/` — the same seam for applications that are not Rust. `include/application-engine.h` is the C mirror of the `Application` trait, and the crate is the shim that turns an engine archive implementing it into an `Application`. See [`docs/protocol/c-application-binding.md`](docs/protocol/c-application-binding.md).
- `examples/c-app-sequencer/` — host library for any C application, plus a generic binary for one that supplies its engine as an archive. Application-agnostic: its only application argument is the state file to open.
- `examples/c-wallet-engine/` — `app-core`'s wallet exported through that C API as `libc_wallet_engine.a`. The reference engine, written in Rust because the seam is an ABI and not a language.
- `examples/c-wallet-sequencer/` — binary crate: `c-wallet-engine` + `c-app-sequencer`. The C-path twin of `wallet-sequencer`, same wallet reached over the seam.
- `examples/canonical-app/` — on-chain scheduler reference implementation.
- `examples/canonical-test/` — e2e test harness for the canonical app.
- `sdk/rust-client/` — Rust client library for the sequencer API.
Expand Down
4 changes: 4 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ Rust edition 2024 / Axum API / SQLite (rusqlite, WAL) / EIP-712 signing / SSZ en
- `sequencer-core/` — shared domain types consumed by both sequencer and scheduler.
- `examples/app-core/` — placeholder wallet app implementing `Application`.
- `examples/wallet-sequencer/` — binary crate: wallet app + sequencer library.
- `examples/c-app-engine/` — C binding of the `Application` trait: the header and the FFI shim.
- `examples/c-app-sequencer/` — host library for any C application, plus a generic binary.
- `examples/c-wallet-engine/` — the wallet exported through the C API as a static library.
- `examples/c-wallet-sequencer/` — binary crate: wallet engine + C host.
- `examples/canonical-app/` — on-chain scheduler reference implementation.
- `examples/canonical-test/` — e2e test harness for the canonical app.
- `sdk/rust-client/` — Rust client library for the sequencer API.
Expand Down
40 changes: 40 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ members = [
"sequencer-core",
"sdk/rust-client",
"examples/app-core",
"examples/c-app-engine",
"examples/c-app-sequencer",
"examples/c-wallet-engine",
"examples/c-wallet-sequencer",
"examples/canonical-app",
"examples/canonical-test",
"examples/wallet-sequencer",
Expand Down
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,10 @@ released even on client disconnect.
- `sequencer/src/storage/`: schema, migrations, SQLite persistence (split per writer role), and replay reads
- `sequencer-core/src/`: shared domain types and interfaces (`Application`, `SignedUserOp`, `SequencedL2Tx`, feed message types)
- `examples/app-core/src/`: wallet prototype implementing `Application`
- `examples/c-app-engine/`: the C binding of `Application` — the header and the FFI shim over an engine archive implementing it
- `examples/c-app-sequencer/`: host library for any C application, plus a generic binary for one supplying its engine as an archive
- `examples/c-wallet-engine/`: the wallet app exported through that C API as a static library — the reference engine
- `examples/c-wallet-sequencer/`: binary crate composing the C host with the wallet engine
- `tests/benchmarks/`: benchmark harnesses and benchmark spec

Related docs:
Expand All @@ -235,6 +239,24 @@ docker pull ghcr.io/cartesi/sequencer-watchdog:vX
# mirror: docker.io/cartesi/sequencer-watchdog:vX
```

## Applications in C

An application does not have to be written in Rust. `examples/c-app-engine/include/application-engine.h` is the C mirror of the `Application` trait: an application implements it into a static archive, and `examples/c-app-sequencer` links that archive into a ready-made sequencer host.

```bash
APPLICATION_ENGINE_LIB=/path/to/libmyapp-engine.a \
APPLICATION_ENGINE_HEADER=/path/to/application-engine.h \
APPLICATION_ENGINE_METHOD_PAYLOAD_LIMIT=1024 \
cargo build -p c-app-sequencer --release

c-app-sequencer --state-file <genesis written by the app's own tool> setup ...
c-app-sequencer --state-file <same file> run ...
```

Those three variables are the whole binding, and nothing else about the application reaches this repository — there is no create path on the seam, so the host cannot be told what application to be, and cannot ask. This matters when the application's canonical on-chain execution must stay free of Rust: the same compiled engine is linked by this host and by the application's own canonical binary, so the two agree by construction rather than by review.

The seam is an ABI, not a language. `examples/c-wallet-engine` is the reference engine and is itself written in Rust: it exports the same `application_engine_*` symbols as `libc_wallet_engine.a` over the same `app-core::WalletApp` that `wallet-sequencer` uses directly. `examples/c-wallet-sequencer` links it, so the workspace builds the whole path without an archive path handed to it, and this repository maintains no C beyond the header. See [`docs/protocol/c-application-binding.md`](docs/protocol/c-application-binding.md) and `just c-wallet-genesis`.

## Prototype Limits

- The `Application` trait exposes snapshot dump/load capability (format in `docs/snapshots/format.md`). The inclusion lane drives the snapshot lifecycle — dump at batch close, promote to finalized on L1 observation, and garbage-collect superseded dumps — and at startup rebuilds application state by loading the latest snapshot and replaying the persisted L2-tx stream from that snapshot's offset. The lifecycle and its rationale (per-range atomic promotion, GC, leasing, crash-safety) are documented in `docs/snapshots/lifecycle.md`. The snapshot is served to the operator's watchdog/indexers over internal-only HTTP routes (`/finalized_state`, `/finalized_state/inclusion_block`, `/latest_snapshot`) — no auth, gated by network-level access control until the planned per-port api split lands.
Expand Down Expand Up @@ -267,6 +289,7 @@ Some tests require [Foundry](https://getfoundry.sh) (`anvil` on PATH). They run
- [`docs/watchdog/README.md`](docs/watchdog/README.md) — watchdog architecture, modules, and test commands.
- [`sequencer-core/`](sequencer-core/) — shared domain types (`Application`, `SignedUserOp`, `Batch`, `Frame`).
- [`examples/app-core/`](examples/app-core/) — placeholder wallet app implementing the `Application` trait.
- [`docs/protocol/c-application-binding.md`](docs/protocol/c-application-binding.md) — the same contract in C, for applications that are not written in Rust.

## License

Expand Down
4 changes: 4 additions & 0 deletions docs/protocol/application-contract.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,10 @@ Trait Contract" is the map. The placeholder wallet
([`examples/app-core/`](../../examples/app-core/)) is the reference impl; a
production app will wrap a Cartesi Machine behind the same trait.

An app that is not written in Rust implements the same contract through a C
header instead. [`c-application-binding.md`](c-application-binding.md) describes
that path; everything below binds it identically.

---

## The execution methods
Expand Down
Loading