stellar/stellar-core · Archived

subsystem-summary-of-rust

read this skill for a token-efficient summary of the rust subsystem

First seen Apr 29, 2026

Installation

$ npx skills add stellar/stellar-core --skill subsystem-summary-of-rust

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Also in this package

Other skills from stellar/stellar-core · top by installs.

npx skills add stellar/stellar-core

Browse all from stellar/stellar-core

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Stars 3.3K
License LICENSE-APACHE.txt
Default branch master
Open issues 257
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 18,354 B
  • docs SUMMARY.md 100 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 2 installs

SKILL.md

Rust Subsystem (Non-Soroban) — Technical Summary

Overview

The rust subsystem provides a Rust static library (ruststellarcore) that is linked into the stellar-core C++ binary. It uses the cxx crate (v1.0.97) to define a bidirectional FFI bridge between C++ and Rust. The subsystem's primary responsibilities are:

  1. Soroban host function invocation — dispatching to the correct protocol-versioned soroban host.
  2. Fee computation — transaction resource fees, rent fees, and rent write fees.
  3. Module caching — pre-compiled WASM module cache for Soroban contracts.
  4. 128-bit integer arithmetic — exposing Rust's native i128 to C++.
  5. Base64 encoding/decoding — used for XDR serialization interop.
  6. Ed25519 signature verification — using ed25519-dalek for faster verification.
  7. Logging bridge — routing Rust log crate output to the C++ spdlog system.
  8. Quorum intersection checking — using the stellar-quorum-analyzer SAT solver.
  9. Utility functions — rustc version, executable path, backtrace capture, XDR version checks.

The crate is built as crate-type = ["staticlib"] (edition 2021, rust-version 1.82.0). Optional features include tracy (profiling), next (pre-release protocol), testutils (test-only code), and unified (IDE-friendly single cargo build).

File Layout

File Role
Cargo.toml Crate metadata, multi-host soroban dependencies, feature flags
src/lib.rs Crate root; declares modules, re-exports bridge symbols, defines tracy_span! macro
src/bridge.rs #[cxx::bridge] module — all FFI type/function declarations
src/common.rs RustBuf/CxxBuf/BridgeError impls; getrustcversion, currentexe, capturecxxbacktrace, checkxdrversionidentities
src/b64.rs tobase64 / frombase64
src/ed25519_verify.rs verifyed25519signature_dalek (unsafe raw-pointer FFI)
src/i128.rs i128add, i128sub, overflow/underflow checks, conversion
src/log.rs StellarLogger implementing log::Log, routes to C++ spdlog
src/quorum_checker.rs networkenjoysquorum_intersection wrapping stellar-quorum-analyzer
src/soroban_invoke.rs invokehostfunction, fee computation, transaction parsing dispatchers
src/sorobanmodulecache.rs SorobanModuleCache struct; per-protocol caches
src/sorobanprotoall.rs Protocol-versioned host modules (p21–p26), dispatch table, adaptors
src/sorobanprotoany.rs Protocol-agnostic host invocation code, mounted inside each pN module
CppShims.h Thin C++ shim functions (shimisLogLevelAtLeast, shimlogAtPartitionAndLevel)
RustBridge.h cxx-generated C++ header with all bridge types and function declarations
RustBridge.cpp cxx-generated C++ implementation (extern "C" thunks, Vec/Box specializations)
RustVecXdrMarshal.h Declares rust::Vec<uint8_t> as valid xdrpp byte buffer type

The CXX Bridge Mechanism

How it works

The bridge is defined in src/bridge.rs inside a #[cxx::bridge] attribute macro on mod rust_bridge. This module contains three sections:

  1. Shared types — structs and enums visible to both sides, defined once:

- CxxBuf (C++→Rust data: wraps UniquePtr<CxxVector<u8>>) - RustBuf (Rust→C++ data: wraps Vec<u8>) - XDRFileHash, InvokeHostFunctionOutput, CxxLedgerInfo, CxxTransactionResources, CxxFeeConfiguration, CxxLedgerEntryRentChange, CxxRentFeeConfiguration, CxxRentWriteFeeConfiguration, CxxI128, FeePair, SorobanVersionInfo - Enums: LogLevel (shared with stellar::LogLevel), BridgeError, QuorumCheckerStatus - QuorumSplit, QuorumCheckerResource

  1. extern "Rust" block (#[namespace = "stellar::rust_bridge"]) — Rust functions callable from C++:

- All functions listed in the "Key Functions" section below. - The opaque type SorobanModuleCache with its methods.

  1. extern "C++" block (#[namespace = "stellar"]) — C++ functions callable from Rust:

- shimisLogLevelAtLeast(partition: &CxxString, level: LogLevel) -> Result<bool> - shimlogAtPartitionAndLevel(partition: &CxxString, level: LogLevel, msg: &CxxString) -> Result<()>

Data passing convention

  • C++ → Rust: Data is passed as CxxBuf containing UniquePtr<CxxVector<u8>> (a C++-allocated std::vector<uint8t>). The Rust side reads from it via data.asslice().
  • Rust → C++: Data is returned as RustBuf containing Vec<u8> (Rust-allocated). The C++ side reads from data (a rust::Vec<uint8_t>).
  • XDR serialization/deserialization is done with ReadXdr/WriteXdr using nonmeteredxdrfromcxxbuf and nonmeteredxdrtorustbuf helper functions with a depth limit of 1000 and length limit matching the buffer size.
  • RustVecXdrMarshal.h allows xdrpp to directly unmarshal from rust::Vec<uint8_t>.

Generated files

RustBridge.h and RustBridge.cpp are generated by the cxxbridge tool. They contain:

  • Full implementations of rust::String, rust::Slice<T>, rust::Box<T>, rust::Vec<T>, rust::Opaque, rust::Error.
  • C struct definitions mirroring the shared types.
  • static_assert checks ensuring LogLevel enum values match between C++ and Rust.
  • extern "C" function declarations for the mangled bridge symbols.
  • C++ wrapper functions in namespace stellar::rust_bridge that call through extern "C" thunks and translate Rust errors to C++ exceptions (rust::Error).
  • Template specializations for rust::Vec<RustBuf>, rust::Vec<XDRFileHash>, rust::Vec<CxxBuf>, etc.
  • rust::Box<SorobanModuleCache> alloc/dealloc/drop specializations.

CppShims.h

Provides simple inline wrapper functions that cxx.rs can call, bridging to C++ APIs that are too complex for cxx to handle directly (e.g., static member functions):

  • shim_isLogLevelAtLeast → Logging::isLogLevelAtLeast
  • shim_logAtPartitionAndLevel → Logging::logAtPartitionAndLevel

Key Data Structures

CxxBuf / RustBuf

Directional byte-buffer wrappers for passing XDR-serialized data across the FFI boundary. CxxBuf owns a std::uniqueptr<std::vector<uint8t>> (C++ allocated). RustBuf owns a Vec<u8> (Rust allocated). Both implement AsRef<[u8]>.

CxxI128

Split representation of 128-bit integer: { hi: i64, lo: u64 }. Used because C++ lacks native i128 on all platforms. Converted to/from Rust i128 via int128helpers::{i128frompieces, i128hi, i128_lo}.

InvokeHostFunctionOutput

Return value of invokehostfunction. Contains:

  • success: bool, isinternalerror: bool
  • diagnostic_events: Vec<RustBuf> (XDR-encoded DiagnosticEvent)
  • cpuinsns, membytes, time_nsecs (and excluding-VM-instantiation variants)
  • resultvalue: RustBuf, contractevents: Vec<RustBuf>, modifiedledgerentries: Vec<RustBuf>, rent_fee: i64

SorobanModuleCache

An opaque Rust type exposed to C++ via rust::Box<SorobanModuleCache>. Holds per-protocol ProtocolSpecificModuleCache instances (p23, p24, p25, and optionally p26 with next feature). Each ProtocolSpecificModuleCache contains a ModuleCache (from soroban-env-host, threadsafe via internal locking) and an AtomicU64 tracking memory consumption. Methods:

  • compile(&mut self, ledger_protocol: u32, wasm: &[u8]) — parse and cache a WASM module for the given protocol.
  • shallow_clone(&self) -> Box<SorobanModuleCache> — clone shared ownership handles for multithreaded compilation.
  • evictcontractcode(&mut self, key: &[u8]) — remove a module from all protocol caches by 32-byte hash.
  • clear(&mut self) — clear all protocol caches.
  • contains_module(&self, protocol: u32, key: &[u8]) -> bool
  • getmembytes_consumed(&self, protocol: u32) -> u64

HostModule

A dispatch table struct (not crossing FFI) containing function pointers for a specific protocol version's soroban host. Fields include maxproto, invokehostfunction, computetransactionresourcefee, computerentfee, computerentwritefeeper1kb, contractcodememorysizeforrent, canparsetransaction, and getsorobanversioninfo. The static array HOSTMODULES holds one entry per protocol version (p21–p25/p26), populated via the protoversionedfunctionsformodule! macro.

ProtocolSpecificModuleCache

Per-protocol cache wrapper (defined in sorobanprotoany.rs). Wraps a ModuleCache from the protocol's soroban-env-host and a CoreCompilationContext (unlimited budget for compilation). Supports compile, evict, clear, containsmodule, getmembytesconsumed, and shallow_clone.

CoreCompilationContext

Implements CompilationContext (= ErrorHandler + AsBudget) with an unlimited budget, used for compiling WASM modules outside of transaction execution.

Key Functions (Exported Rust → C++)

Soroban Host Invocation

  • invokehostfunction(configmaxprotocol: u32, enablediagnostics: bool, instructionlimit: u32, hfbuf: &CxxBuf, resources: CxxBuf, restoredrwentryindices: &Vec<u32>, sourceaccount: &CxxBuf, authentries: &Vec<CxxBuf>, ledgerinfo: CxxLedgerInfo, ledgerentries: &Vec<CxxBuf>, ttlentries: &Vec<CxxBuf>, baseprngseed: &CxxBuf, rentfeeconfiguration: CxxRentFeeConfiguration, modulecache: &SorobanModuleCache) -> Result<InvokeHostFunctionOutput> — Dispatches to the correct protocol-versioned host via gethostmoduleforprotocol. Wraps the call in panic::catch_unwind.

Fee Computation

  • computetransactionresourcefee(configmaxprotocol: u32, protocolversion: u32, txresources: CxxTransactionResources, feeconfig: CxxFeeConfiguration) -> Result<FeePair> — Returns (nonrefundablefee, refundable_fee).
  • computerentfee(configmaxprotocol: u32, protocolversion: u32, changedentries: &Vec<CxxLedgerEntryRentChange>, feeconfig: CxxRentFeeConfiguration, currentledger_seq: u32) -> Result<i64>
  • computerentwritefeeper1kb(configmaxprotocol: u32, protocolversion: u32, bucketlistsize: i64, fee_config: CxxRentWriteFeeConfiguration) -> Result<i64>
  • contractcodememorysizeforrent(configmaxprotocol: u32, protocolversion: u32, contractcodeentry: &CxxBuf, cpucostparams: &CxxBuf, memcostparams: &CxxBuf) -> Result<u32> — Only valid for protocol ≥ 23.

Transaction Parsing

  • canparsetransaction(configmaxprotocol: u32, protocolversion: u32, xdr: &CxxBuf, depthlimit: u32) -> Result<bool> — Checks if a TransactionEnvelope XDR can be deserialized in the given protocol.

128-bit Integer Arithmetic

  • i128_add(lhs: &CxxI128, rhs: &CxxI128) -> Result<CxxI128>
  • i128_sub(lhs: &CxxI128, rhs: &CxxI128) -> Result<CxxI128>
  • i128addwill_overflow(lhs: &CxxI128, rhs: &CxxI128) -> Result<bool>
  • i128subwill_underflow(lhs: &CxxI128, rhs: &CxxI128) -> Result<bool>
  • i128fromi64(val: i64) -> Result<CxxI128>
  • i128isnegative(val: &CxxI128) -> Result<bool>
  • i128i64eq(lhs: &CxxI128, rhs: i64) -> Result<bool>

Ed25519 Verification

  • verifyed25519signaturedalek(publickeyptr: const u8, signatureptr: const u8, messageptr: *const u8, messagelen: usize) -> bool — Unsafe raw-pointer interface. Uses ed25519-dalek's verify_strict (rejects small-order points, matching libsodium). Never panics; returns false for invalid input.

Base64

  • to_base64(b: &CxxVector<u8>, s: Pin<&mut CxxString>) — Encode bytes to base64.
  • from_base64(s: &CxxString, b: Pin<&mut CxxVector<u8>>) — Decode base64 with error-tolerant stripping of invalid characters.

Logging

  • init_logging(maxLevel: LogLevel) -> Result<()> — Initializes the StellarLogger as the global Rust logger, routing to C++ spdlog. Uses AtomicBool for one-time initialization. Log partitions (e.g., TX, Ledger, SCP) are defined in log::partition and must match util/LogPartitions.def on the C++ side.

Quorum Checker

  • networkenjoysquorumintersection(nodes: &Vec<CxxBuf>, quorumset: &Vec<CxxBuf>, potentialsplit: &mut QuorumSplit, resourcelimit: &QuorumCheckerResource, resourceusage: &mut QuorumCheckerResource) -> Result<QuorumCheckerStatus> — Returns UNSAT (quorum intersection holds), SAT (split found, populates potentialsplit), or UNKNOWN. Time limit enforced internally; memory limit is a hard abort via global allocator.

Module Cache

  • newmodulecache() -> Result<Box<SorobanModuleCache>>
  • Methods on SorobanModuleCache: compile, shallowclone, evictcontractcode, clear, containsmodule, getmembytes_consumed.

Utility

  • getrustcversion() -> String
  • current_exe() -> Result<String>
  • capturecxxbacktrace() -> String — Uses backtrace crate; filters out initial Rust frames and libc frames.
  • getsorobanversioninfo(coremax_proto: u32) -> Vec<SorobanVersionInfo> — Returns version info for all linked soroban hosts. Panics if no host supports the given protocol.
  • checksensiblesorobanconfigforprotocol(coremaxproto: u32) — Validates HOSTMODULES are in ascending order and cover the max protocol.
  • checkxdrversion_identities() -> Result<()> — Compares XDR file SHA256 hashes across crates.

Multi-Protocol Soroban Host Architecture

Design

stellar-core links multiple versions of soroban-env-host simultaneously, one per protocol version range. Each is labeled by its maximum supported protocol (e.g., soroban-env-host-p21 supports protocols up to 21). At runtime, gethostmoduleforprotocol(configmaxproto, ledger_protocol) selects the appropriate host.

Implementation pattern

sorobanprotoall.rs defines adaptor modules p21, p22, p23, p24, p25, and conditionally p26 (behind next feature). Each adaptor:

  1. Imports its specific sorobanenvhostpNN crate and re-exports it as sorobanenv_host.
  2. Provides adapter functions for API differences between host versions (e.g., different field names in TransactionResources, RentFeeConfiguration).
  3. Mounts sorobanprotoany.rs as a child module — this file is the same source but "sees" a different super::sorobanenvhost in each context.
  4. Defines stub types (ModuleCache, ErrorHandler, CompilationContext) for older protocols (p21, p22) that don't support the reusable module cache API.

Protocol dispatch

The HOSTMODULES static array maps protocol ranges to HostModule structs containing function pointers. gethostmoduleforprotocol iterates this array: each entry's implied minimum protocol is one more than the previous entry's maxproto (first entry starts at 0).

Aliases

  • soroban_curr — alias for the latest non-next host (p25, or p26 with next).
  • protocolagnostic — re-exports from p24 that are stable across versions (e.g., int128helpers, make_error).

Key Data Flows

C++ → Soroban Invocation → C++

  1. C++ constructs CxxBuf objects containing XDR-serialized data (host function, resources, ledger entries, etc.) and a CxxLedgerInfo.
  2. Calls stellar::rustbridge::invokehost_function(...) which crosses the FFI boundary.
  3. Rust dispatches to the correct HostModule based on (configmaxprotocol, ledgerinfo.protocolversion).
  4. The protocol-specific invokehostfunction in sorobanprotoany.rs deserializes XDR, creates a Budget, optional trace hook, and calls through to sorobanenvhost::e2einvoke::invokehost_function.
  5. Results are re-serialized to RustBuf vectors and returned as InvokeHostFunctionOutput.
  6. The C++ wrapper in RustBridge.cpp unwraps the result or throws rust::Error on failure.

Logging (Rust → C++)

  1. Rust code calls log::info!() etc.
  2. StellarLogger::log() converts the level and calls shim_logAtPartitionAndLevel via the extern "C++" bridge.
  3. The shim calls Logging::logAtPartitionAndLevel in C++.

Module Cache Lifecycle

  1. C++ calls newmodulecache() to get a rust::Box<SorobanModuleCache>.
  2. Calls compile(protocol, wasm_bytes) to cache WASM modules (typically on startup and during catchup).
  3. The cache is passed by reference to invokehostfunction.
  4. shallow_clone() creates shared-ownership handles for multithreaded use.
  5. evictcontractcode(key) removes entries; clear() empties all caches.

Error Handling

  • All fallible Rust functions return Result<T, Box<dyn std::error::Error>> (or Result<T, HostError>).
  • cxx converts Rust Err returns into C++ rust::Error exceptions.
  • invokehostfunction and networkenjoysquorumintersection additionally wrap their core logic in panic::catchunwind to convert Rust panics into errors rather than unwinding across the FFI boundary.
  • The quorum checker's memory limit is a hard abort (non-catchable) by design.
  • CoreHostError enum wraps either a HostError from soroban or a general String message.

Dependencies

Crate Purpose
cxx 1.0.97 C++/Rust FFI bridge framework
base64 0.13.1 Base64 encode/decode
log 0.4.19 Rust logging facade
ed25519-dalek 2.1.1 Ed25519 signature verification
itertools 0.10.5 Iterator utilities
backtrace 0.3.76 C++ backtrace capture (with cpp_demangle)
rand 0.8.5 RNG (must match soroban's version)
rustc-simple-version 0.1.0 Compile-time rustc version string
tracy-client 0.17.0 Tracy profiling (optional)
stellar-quorum-analyzer SAT-based quorum intersection checking
soroban-env-host-pNN Protocol-specific Soroban hosts (p21–p26)
soroban-test-wasms Pre-compiled test WASM binaries
soroban-synth-wasm Random WASM generation for testing

Build Notes

  • The default build does not use the optional soroban-env-host-pNN deps from Cargo.toml. Instead, each host is built as a separate cargo invocation and linked in (see src/Makefile.am). This avoids Cargo's dependency unification.
  • The unified feature enables all hosts as direct dependencies for IDE usage. This perturbs Cargo.lock — changes should not be committed.
  • Tracy feature flags must match between the Rust crate and the C++ lib/tracy submodule version.