SpaceDB
Note: this project is still under active development and should be considered experimental.
SpaceDB is a cryptographically verifiable data store and universal accumulator for the Spaces protocol. It's a Merkle-ized binary trie described in the Merklix paper and explained in detail here.
Features
- Fast, portable, single-file database.
- MVCC-based concurrency control with multi-reader/single-writer lock-free access.
- Provides compact proofs of membership/non-membership for batches of elements through subtrees.
- Subtrees act as cryptographic accumulators and can be updated independently.
no_stdsupport, particularly for use within RISC0 zkVM and leverages SHA256 acceleration.- Accumulator keeps a constant size state of a single 32-byte tree root.
Usage
use Database;
let db = open?;
// Insert some data
let mut tx = db.begin_write?;
for i in 0..100
tx.commit?;
let mut snapshot = db.begin_read?;
println!;
// Prove a subset of the keys
let keys_to_prove: =
.map
// prove exclusion of some other keys
.chain
.map
.collect;
// Reveal relevant nodes needed to prove the specified set of keys
let mut subtree = snapshot.prove?;
// Will have the exact same root as the snapshot
println!;
// Inclusion and exclusion proofs
assert!;
assert!;
// Proving exclusion of "other100" fails since we didn't reveal
// relevant branches needed to traverse its path in this subtree
assert!;
Subtrees
Subtrees can function as cryptographic accumulators, allowing clients to verify and update their state without keeping a database.
// Client maintains a 32-byte tree root
let mut accumulator_root = snapshot.root?;
assert_eq!;
// Update leaves
for in subtree.iter_mut
// Inserting a non-existent key (must be provably absent)
let key = subtree.hash;
subtree.insert.unwrap;
// Updating the accumulator root
accumulator_root = subtree.root.unwrap;
Using in RISC0 zkVM
Subtrees work in no_std environments utilizing the SHA256 accelerator when running inside the RISC0 zkVM.
[]
= { = "0.1", = false }
The hash-idx feature enables an optional sqlite-backed sidecar that accelerates prove and compute_root on large trees:
[]
= { = "0.1", = ["hash-idx"] }
Using Subtrees in wasm
If building from source:
wasm-pack build --target nodejs --features wasm --no-default-features
then:
import from "../pkg/spacedb.js";
const raw = ; // or null for an empty subtree
const subtree = ;
const root = subtree.;
console.log;
console.log;
Key Iteration
Iterate over all keys in a given snapshot:
let db = open?;
let snapshot = db.begin_read?;
for in snapshot.iter.filter_map
Snapshot iteration
Iterate over all snapshots:
let db = open?;
for snapshot in db.iter.filter_map
Prior Art
Merkle-ized tries, including variations like Patricia tries and Merkle prefix trees, are foundational structures that have been used in numerous projects and cryptocurrencies. Some other libraries that implement some form of Merkle-ized binary tries include liburkel which this library initially drew some inspiration from — although SpaceDB is generally around ~20% faster, and multiproof, but they either lack memory safety, core features such as subtrees/accumulators needed for Spaces protocol or are unmaintained. Other popular cryptographically verifiable data stores include Trillian used for Certificate Transparency
License
This project is licensed under the Apache 2.0.