Relational state management on-chain for different types of queries
Cubane does not embed a SQL database in a blockchain. It treats relational semantics as a protocol-level abstraction over deterministic, versioned key-value state, and changes the execution strategy for each query. Ten example statements show how. Not a database inside a chain A common assumption about encrypted relational execution is that it means running a conventional database engine, such as PostgreSQL or MySQL, inside a blockchain node. That is not what Cubane does, and the difference matters for how state changes are managed. We manage state changes on top of a relational abstraction, and the relational abstraction is not the same thing as relational database management. Tables, columns, constraints and joins exist as a contract that developers and the protocol share. Underneath, there is no database server. There is deterministic, versioned key-value state that every node holds and every node can replay. Cubane does not put a conventional SQL database “inside the blockchain.” It makes relational semantics a protocol-level abstraction over deterministic versioned KV state, with the execution strategy changing according to the confidentiality and computational requirements of each query. Abstraction versus management A relational database management system is a piece of software that owns its storage, its locks, its query planner and its access control. It is operated by someone, and the people using it trust that operator. A relational abstraction in Cubane is a set of rules for how relational statements compile into operations on shared state. The rules are part of the protocol. The resulting state transitions are verified the same way as any other transaction, and the storage beneath them is the same versioned key-value store the rest of the chain uses.Two different things Conventional RDBMS Cubane relational abstraction Storage Pages and files on one operator’s machine Deterministic versioned KV state, committed per tick Trust The operator is trusted Every node reaches the same result by replay Concurrency Locks or local MVCC Version vectors (row, tick, branch) shared by all nodes Execution One engine for every query Strategy chosen per query by confidentiality and compute need Privacy Access control around plaintext Per-column scheme, mode and visibility Deletion Rows are removed Tombstone version; erasure by key destruction State changes on the abstraction Every relational statement, whether it reads, inserts, updates or deletes, becomes a set of versioned key-value operations. A read is a load of a specific version at a snapshot tick. A write creates a new version at the current tick. A delete creates a tombstone. Nothing is overwritten in place. The layers that perform this compilation are strictly separated. Each consumes only the layer below and exposes a typed contract upward, and the bottom layer is required to work without knowing whether a value is plaintext or ciphertext.The abstraction stack L1 Statement and canonical ASTDeterministic parse: sorted children, no floating point. L2 Schema registry and column policyTables, constraints and a (scheme, mode, visibility) tuple per column. L3 MVCC and conflict resolutionVersions identified by (row, tick, branch), independent of value. L4 KV and index projectionRows to keys; four index kinds, each with a declared leakage class. L5 Versioned KV state and commitmentsKey, value, version, tombstone. Merkle per tick, KZG per epoch. One statement, text to commitment The path a statement takes is the same for every query type. What changes is the plan produced at the policy step, and therefore which execution strategy runs.Statement lifecycle 01StatementParsed into a canonical syntax tree 02Policy lookupEach column’s scheme, mode and visibility 03PlanStrategy and fee quote fixed before execution 04Versioned opsLoad, Store, Delete, PrefixScan, QueryIndex 05CommitmentNew state root bound into the STU How a strategy is chosen Each column carries one validated tuple. The scheme says how the value is represented: plaintext, FHE ciphertext, ABE-encrypted plaintext or obfuscated plaintext. The mode says how it may be computed on: full FHE, hybrid, proof-only, or MPC and FHE combined. The visibility says who may see it. When encrypted computation is needed, the compiler chooses a scheme from a versioned cost table. TFHE handles comparisons and branches. CKKS handles packed approximate arithmetic such as sums and averages. BGV and BFV handle exact integer arithmetic such as balances. The choice follows a fixed precedence of query pragma, then table, then namespace, then protocol default, so it is never decided at random at runtime. The examples that follow use one illustrative schema and illustrative syntax. The comments under each statement show the plan the abstraction produces.Illustrative schema CREATE TABLE accounts ( account_id BYTES POLICY (plaintext, hybrid, public), branch TEXT POLICY (plaintext, hybrid, public), balance INT64 POLICY (bgv, full_fhe, confidential), amount INT64 POLICY (ckks, full_fhe, confidential) ); CREATE TABLE customers ( customer_id BYTES POLICY (plaintext, hybrid, public), national_id TEXT POLICY (abe, proof_only, compliance), risk_score INT32 POLICY (tfhe, full_fhe, confidential) ); Example 1: public point read The simplest case. Every column involved is public, so no encryption is needed. The index lookup and the load happen against a snapshot at a specific tick, which means every node returns the same value even while new versions are being written.Statement SELECT branch FROM accounts WHERE account_id = :id; — policy accounts.branch (plaintext, hybrid, public) — index plaintext B-tree on account_id — ops QueryIndex -> Load K @ snapshot tick T — output plaintext value Example 2: public aggregate Counting rows by a public column is also a plaintext operation. The abstraction still requires a deterministic plan: the scan order is fixed and the grouping is computed with integer arithmetic, so the result can be reproduced on any node.Statement SELECT branch, COUNT(*) FROM accounts GROUP BY branch; — policy all referenced columns public — strategy plaintext aggregation in the read path — ops PrefixScan over accounts @ tick T — output plaintext counts Example 3: confidential aggregate Here the query mixes visibilities. The planner splits it: the public filter runs as an ordinary predicate, and the sum runs homomorphically over encrypted amounts, packed so that many values are added in a single operation. The result is ciphertext, accompanied by a public zero-knowledge label. Dashboards and indexes consume the label. […]