Architecture¶
OpaqueDB is a set of C++20 libraries with a strict, one-directional dependency
graph. Each src/<dir> is its own CMake library target, and dependencies may
only point downward. CMake target visibility enforces the direction, so a
forbidden include fails to link.
Layering¶
config, core foundational; everything may depend on them
config <- log (spdlog; the one logging entry point)
core <- crypto <- backend (interface + concrete backends)
core <- storage
core <- sql <- planner
config, core, storage, crypto <- admin
all of the above <- auth, cluster, server, client, cli
Rules that hold:
- crypto is the only SEAL boundary. It reads FHE parameters from config and knows nothing about SQL.
- storage stores opaque bytes. It knows nothing about crypto and does not link SEAL. Slot geometry reaches it as plain integers, never SEAL types.
- backends live under
src/backend/<name>/(for examplebackend/reference). Each is its own target that links thebackendinterface, depends on crypto and on the columns handed to it, and not on SQL or transport. - main.cpp only wires things together. It holds no logic.
Components¶
| Layer | Responsibility |
|---|---|
config |
The one place settings live. Resolved once into an immutable Config and injected. |
core |
Foundational types and codecs: key codec, slot codec, record codec, schema. |
log |
Logging configured once by log::Init over spdlog. |
crypto |
The SEAL boundary: encrypt, decrypt, key handling, parameter validation. |
backend |
The matcher interface; concrete backends evaluate the encrypted scan. |
storage |
Immutable epoch segments, WAL, manifests, catalog. Opaque bytes only. |
sql / planner |
Parse CREATE TABLE and queries; build the logical plan. |
admin |
Transport-agnostic AdminService (publish, list, rollback, status, schema, principals) and KeyringStore. |
auth |
Authenticator (token / mtls / none), gRPC-free; RequestGate runs auth then rate-limit. |
cluster |
etcd membership, lease and keepalive, leader election, shard-map publish. |
server |
gRPC services, the query engine, the repository manager, publish path. |
client |
The one wire query client, client::QueryClient. |
cli |
CLI11 commands under src/cli/commands/. |
Single sources of truth¶
The project is strict about not duplicating definitions:
- The
.protofiles define the wire types. Nothing hand-duplicates them. - Common build, test, lint, and packaging commands live once in the
Makefile. - The
Configstruct is the only place settings live. - The bit-sliced key codec (
core::key_codec) and the SIMD plane layout (core::slot_codec) live once incore. - The default config is one file,
config/opaquedb.default.toml, embedded at build time. - The version is the CMake
project(VERSION)only. - The schema lives once in the epoch manifest; the FHE parameter set lives once in config.
- Management logic lives once in
AdminService; the gRPC adapter and the CLI are thin clients over it. - Logging is configured once by
log::Init.
Libraries¶
All dependencies flow through vcpkg in manifest mode,
pinned by the baseline in vcpkg.json.
| Library | Used for |
|---|---|
| Microsoft SEAL | BFV homomorphic encryption, the crypto boundary. |
| gRPC + Protobuf | Client and node-to-node RPC, the wire contract. |
| Abseil | absl::Status / absl::StatusOr and core utilities. |
| etcd-cpp-apiv3 | Cluster membership, leader election, shard map. Vendored as an overlay port, core-only. |
| CLI11 | Command-line parsing. |
| replxx | Line editing and tab completion in the repl shell. |
| spdlog | The single logging entry point. |
| tomlplusplus | Config file parsing. |
| nlohmann-json | Epoch manifests and JSON logs. |
| GoogleTest | The test suite. |
Error handling¶
Fallible API boundaries return absl::Status or absl::StatusOr. Exceptions
are reserved for programmer errors. SEAL throws on bad input, so the crypto
boundary catches and converts to a status. There are no silent failures and no
ad hoc error codes.