Skip to content

Explore a Rust interface for CCF applications - #8200

Merged
Amaury Chamayou (achamayou) merged 41 commits into
mainfrom
achamayou-rust-interface-exploration
Sep 24, 2026
Merged

Amaury Chamayou (achamayou) merged 41 commits into
mainfrom
achamayou-rust-interface-exploration

Conversation

@achamayou

@achamayou Amaury Chamayou (achamayou) commented Aug 24, 2026 •

Copy link
Copy Markdown
Member

Summary

This PR explores what it would take to support native CCF applications written in Rust while keeping the integration boundary small and explicit.

It introduces:

  • a C ABI bridge between the CCF host and Rust application code;
  • an initial ccf-app Rust crate for endpoint registration, request and response handling, authentication selection, and raw-byte KV access;
  • CMake support for building and packaging Rust applications alongside native CCF applications;
  • a basic Rust records application, end-to-end test coverage, and user documentation.

Goal

The goal is to evaluate the viability and ergonomics of Rust as another native CCF application language without exposing C++ implementation details across the boundary. The proposed API deliberately starts small so that ownership, lifetime, panic containment, transaction, concurrency, and packaging concerns can be reviewed before expanding the surface area.

Exploration status

This is exploratory work, not a commitment to a stable or production-supported Rust SDK. The current interface intentionally omits advanced endpoint configuration, custom authentication policies, historical queries, indexing, and commit callbacks. Feedback is especially welcome on the ABI design, safety guarantees, SDK ergonomics, and long-term maintenance implications.

This replays the work from achamayou/CCF#107 onto the current microsoft/CCF main branch so it can be discussed and evaluated in the upstream repository.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces exploratory Rust support for native CCF applications through a C ABI bridge and Rust SDK.

Changes:

  • Adds endpoint, authentication, response, and raw KV APIs.
  • Adds Cargo/CMake integration and packaging.
  • Adds a sample application, E2E coverage, documentation, and changelog entry.

Custom instructions used

  • .github/copilot-instructions.md
  • .github/instructions/changelog.instructions.md
  • .github/instructions/reviewing.instructions.md

Reviewed changes

Copilot reviewed 17 out of 19 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
CHANGELOG.md Announces Rust application support.
CMakeLists.txt Installs Rust sources and registers the E2E test.
cmake/ccf_app.cmake Adds the Rust application build helper.
cmake/gersemi_definitions.cmake Registers the helper for CMake formatting.
include/ccf/rust_ffi.h Defines the public C ABI.
src/rust/app_bridge.cpp Implements the C++ bridge and endpoint registry.
src/rust/ccf-app/Cargo.toml Defines the Rust SDK crate.
src/rust/ccf-app/Cargo.lock Locks the SDK crate.
src/rust/ccf-app/src/lib.rs Implements the Rust-facing API and handlers.
samples/CMakeLists.txt Includes the Rust sample.
samples/apps/basic_rust/CMakeLists.txt Builds the sample application.
samples/apps/basic_rust/Cargo.toml Defines the sample crate.
samples/apps/basic_rust/Cargo.lock Locks sample dependencies.
samples/apps/basic_rust/rust-toolchain.toml Pins Rust 1.90.
samples/apps/basic_rust/src/lib.rs Implements records and health endpoints.
tests/basic_rust.py Exercises authentication and KV behavior.
doc/build_apps/index.rst Adds Rust to the application overview.
doc/build_apps/get_started.rst Links Rust build guidance.
doc/build_apps/example_rust.rst Documents the initial Rust interface.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/rust/app_bridge.cpp Outdated
Comment thread cmake/ccf_app.cmake Outdated
Comment thread src/rust/ccf-app/src/lib.rs
Comment thread doc/build_apps/example_rust.rst Outdated
Comment thread doc/build_apps/example_rust.rst Outdated
Comment thread include/ccf/rust_ffi.h Outdated
@achamayou
Amaury Chamayou (achamayou) force-pushed the achamayou-rust-interface-exploration branch from b50fb7c to 66b1b47 Compare August 26, 2026 14:42
Copilot AI and others added 11 commits August 28, 2026 15:05
Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Preserve compaction retry semantics, reject unsupported HTTP status codes, and keep the CI test bucket inventory in sync.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Stabilize the C ABI, preserve Cargo dependency tracking, register Rust unit tests, enforce unwind panics, and clarify native application trust semantics.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 20 out of 22 changed files in this pull request and generated 5 comments.

Comment thread CHANGELOG.md Outdated
Comment thread src/rust/app_bridge.cpp
Comment thread src/rust/ccf-app/src/lib.rs Outdated
Comment thread doc/build_apps/example_rust.rst Outdated
Comment thread src/rust/ccf-app/src/lib.rs
Copilot AI and others added 3 commits August 29, 2026 08:52
Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Co-authored-by: achamayou <4016369+achamayou@users.noreply.github.com>
Co-authored-by: cjen1-msft <chrisjensen@microsoft.com>
Comment thread src/rust/ccf-app/src/lib.rs Outdated
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment thread src/rust/ccf-app/src/lib.rs Outdated
Comment thread src/rust/ccf-app/src/lib.rs
Comment thread CHANGELOG.md Outdated
Comment thread doc/build_apps/example_rust.rst
Comment thread doc/build_apps/index.rst Outdated
- Install a panic hook from export_app! which does not report panics
  raised by the application's registration function, handlers, or
  handler destructors, since Rust's default hook writes panic messages,
  which may contain request or KV data, to host-visible stderr. Other
  panics, including those from CCF's own Rust code sharing the hook,
  are forwarded to the previous hook.
- Permit empty EndpointError codes in the host bridge, matching
  RpcContext::set_error, instead of replacing them with a generic 500.
- Assert in the e2e test that panic payloads do not reach node output,
  and cover empty error codes.
- Move the changelog entry to 7.0.17 and state the experimental support
  status in the Rust docs, without implying API schema support.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Each Rust staticlib contains its own copy of the Rust standard library,
so a Rust application's staticlib and libccf_rs.a could not both be
linked into a release (LTO) build: rust_eh_personality,
std::panicking::EMPTY_PANIC and ARGV_INIT_ARRAY were defined twice.
Debug builds only linked because the linker skipped the second,
identical copy of each std archive member.

- ccf-app depends on ccf-rs, so a Rust application's staticlib contains
  CCF's own Rust code and a single standard library.
- ccf-rs is also built as an rlib. CMake builds libccf_rs.a with
  cargo rustc --crate-type staticlib, because Cargo does not apply LTO
  to a library which is also built as an rlib.
- ccf_rs links the consuming target's CCF_RUST_APP_LIB, set by
  add_ccf_rust_app, in place of libccf_rs.a.
- Install the TAV sources needed to build ccf-rs against an installed
  CCF, pass the C toolchain to the SDK unit tests, and document that a
  binary can only link one Rust staticlib.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Each Rust staticlib exports its own Rust runtime, so linking libccf_rs.a
with a Rust application archive failed in release builds with duplicate
runtime symbols. Avoid rebuilding CCF's Rust dependency graph in every
application by isolating the existing archive instead:

- combine libccf_rs.a into one relocatable object;
- keep only the cose_* and tav_* C ABI symbols global;
- verify at build time that required exports remain and no implementation
  symbols escape;
- restore ccf-app as a standalone SDK dependency, and install only that
  SDK rather than CCF's Rust implementation sources.

CCF and the application then retain independent, locally scoped Rust
runtimes while continuing to communicate exclusively through C ABIs.
Rust application builds once again compile only the application, ccf-app,
and their own Cargo dependencies.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The CMake format check (gersemi 0.27.0) in scripts/ci-checks.sh failed on
VMSS Virtual A because the FATAL_ERROR message() call exceeded the line
length limit. Wrap the arguments as gersemi expects.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread src/rust/ccf-app/src/lib.rs Outdated
Comment thread src/kv/compacted_version_conflict.h Outdated
Comment thread src/rust/app_bridge.cpp Outdated
Build and export the C++ Rust application bridge as a framework-owned
object target rather than compiling its source in each application. This
lets the bridge use CCF's private CompactedVersionConflict definition
without promoting that implementation detail to the public C++ API.

Restore the exception to src/kv, remove the public shim, make the panic
strategy guard require unwind directly, and add an end-to-end regression
which deterministically forces a Rust endpoint compaction conflict and
observes its transparent retry.

Also teach coverage handling about object libraries so the installed
bridge remains instrumented without being reported as a standalone
coverage binary.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Comment thread src/rust/app_bridge.cpp Outdated
Select both supported Rust authentication policies explicitly and throw
if an unexpected value reaches endpoint registration, rather than
implicitly treating every non-user-cert value as unauthenticated.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@achamayou
Amaury Chamayou (achamayou) merged commit 7da4304 into main Sep 24, 2026
12 checks passed
@achamayou
Amaury Chamayou (achamayou) deleted the achamayou-rust-interface-exploration branch September 24, 2026 16:59
Amaury Chamayou (achamayou) added a commit that referenced this pull request Sep 28, 2026
#8200 was squash-merged into main, so resolve by taking main's final
Rust interface and re-applying only this branch's documentation commit.
Keep main's experimental warning, bridge/linking notes and panic-hook
support, and update docs that described superseded behaviour: the
installed bridge is now a precompiled object, and empty error codes
are accepted.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Amaury Chamayou (achamayou) added a commit that referenced this pull request Sep 28, 2026
Restore the trait's summary from #8200, and name the trait in the guide's
handler rules instead of listing its Send and Sync bounds.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants