Include updates to the notes here if you discover important details while working, or if the notes become outdated.
Rust bindings for libmdbx (MDBX database). Crate name: signet-libmdbx.
- You MUST NOT expose raw pointers to MDBX types via getters.
- You MUST maintain zero-copy semantics for read operations in all new interfaces.
- You MUST read and respect
SAFETYcomments throughout the codebase. - You MUST NOT introduce new dependencies without approval.
- All FFI calls MUST be made in the
opsmodule. - All access of the ops module MUST be done within a
with_txn_ptrclosure.
When making changes to this codebase you MUST remember and conform to the MDBX
synchronization model for transactions and cursors. Access to raw pointers MUST
be mediated via the TxAccess trait.
Environment- Database environment (insrc/sys/environment.rs)TxSync<K>- Transaction with kind marker RO/RW (insrc/tx/sync.rs)TxUnsync<K>- Unsynchronized transaction with kind marker RO/RW (insrc/tx/unsync.rs)Database- Handle to a database, storesdbi+DatabaseFlags(insrc/tx/database.rs)Cursor<'tx, K>- Database cursor, stores&Transaction, raw cursor ptr, andDatabase(insrc/tx/cursor.rs)
let db = txn.open_db(None).unwrap(); // Returns Database (has dbi + flags)
let cursor = txn.cursor(db).unwrap(); // Takes Database, NOT raw dbiDUP_SORT/DUP_FIXED methods validate flags at runtime:
require_dup_sort()returnsMdbxError::RequiresDupSortrequire_dup_fixed()returnsMdbxError::RequiresDupFixed
Methods requiring DUP_SORT: first_dup, last_dup, next_dup, prev_dup, get_both, get_both_range
Methods requiring DUP_FIXED: get_multiple, next_multiple, prev_multiple
MDBX's C layer aborts the process (via cASSERT) on certain constraint
violations — notably INTEGER_KEY size mismatches and oversized keys/values.
These aborts cannot be caught.
Our validation model (in src/tx/assertions.rs):
- Debug builds:
debug_assertchecks catch constraint violations in Rust before they reach FFI. This includes key/value size limits, INTEGER_KEY length (must be 4 or 8 bytes), INTEGER_DUP length, and append ordering. - Release builds: No checks are performed. Invalid input passes through to MDBX, which may abort the process.
- Benchmarks and fuzz targets: MUST constrain inputs to valid ranges. Do not feed arbitrary-length keys to INTEGER_KEY databases or oversized keys/values to any database. The fuzz/bench harness is responsible for generating valid input, not the library.
This is intentional. The library trusts callers in release mode for performance. The debug assertions exist to catch bugs during development.
MdbxError- FFI/database errors (insrc/error.rs)ReadError- Wraps MdbxError + decoding errors for read operationsMdbxResult<T>=Result<T, MdbxError>ReadResult<T>=Result<T, ReadError>
src/
lib.rs - Re-exports
error.rs - MdbxError, ReadError
flags.rs - DatabaseFlags, WriteFlags, etc.
codec.rs - TableObject trait
tx/
mod.rs
assertions.rs - Debug assertions for key/value constraints
cursor.rs - Cursor impl
database.rs - Database struct
sync.rs - Transaction impl
unsync.rs - Unsynchronized transaction impl
iter.rs - Iterator types
sys/
environment.rs - Environment impl
tests/
cursor.rs - Cursor tests
transaction.rs - Transaction tests
environment.rs - Environment tests
proptest_kv.rs - Property tests: key/value operations
proptest_cursor.rs - Property tests: cursor operations
proptest_dupsort.rs - Property tests: DUPSORT operations
proptest_dupfixed.rs - Property tests: DUPFIXED operations
proptest_iter.rs - Property tests: iterator operations
proptest_nested.rs - Property tests: nested transactions
benches/
cursor.rs - Cursor read benchmarks
cursor_write.rs - Cursor write benchmarks
transaction.rs - Transaction benchmarks
db_open.rs - Database open benchmarks
reserve.rs - Reserve vs put benchmarks
nested_txn.rs - Nested transaction benchmarks
concurrent.rs - Concurrency benchmarks
scaling.rs - Scaling benchmarks
deletion.rs - Deletion benchmarks
iter.rs - Iterator benchmarks
utils.rs - Benchmark utilities
fuzz/
fuzz_targets/ - cargo-fuzz targets (FFI/unsafe boundary hardening)
cargo t # Run all tests
cargo t --test cursor # Run cursor tests only
cargo clippy --all-features --all-targets
cargo clippy --no-default-features --all-targets
cargo +nightly fmtA Claude hook in .claude/settings.json runs .claude/hooks/pre-push.sh
before every git push. The push is blocked if any check fails. The checks:
cargo +nightly fmt -- --checkcargo clippy --all-targets --all-features -- -D warningscargo clippy --all-targets --no-default-features -- -D warningsRUSTDOCFLAGS="-D warnings" cargo doc --no-deps
Clippy and doc warnings are hard failures.
Before committing, run the Docker Linux environment to verify changes pass on Linux:
docker build -t mdbx-linux-tests . && docker run --rm mdbx-linux-testsThis SHOULD be run alongside local tests and linting, especially for changes that:
- Modify build configuration
- Add new dependencies
- Change platform-specific code