cnidarium/lib.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91
//! Storage and management of chain state, backed by Jellyfish Merkle Trees and RocksDB.
//!
//! This crate provides a versioned, verifiable key-value store that also
//! supports lightweight, copy-on-write snapshots and transactional semantics.
//! The [`Storage`] type is a handle for an instance of a backing store,
//! implemented using RocksDB. The storage records a sequence of versioned
//! [`Snapshot`]s. The [`Snapshot`] type is a lightweight snapshot of a particular
//! version of the chain state.
//!
//! Each [`Snapshot`] instance can also be used as the basis for a copy-on-write
//! fork to build up changes before committing them to persistent storage. The
//! [`StateDelta`] type collects a group of writes, which can then be applied to
//! the (in-memory) [`StateDelta`] overlay. Finally, the changes accumulated in the
//! [`StateDelta`] instance can be committed to the persistent [`Storage`].
//!
//! Reads are performed with the [`StateRead`] trait, implemented by both
//! [`Snapshot`] and [`StateDelta`], and reflect any currently cached writes.
//! Writes are performed with the [`StateWrite`] trait, which is only
//! implemented for [`StateDelta`].
//!
//! The storage system provides three data stores:
//!
//! * A verifiable key-value store, with UTF-8 keys and byte values, backed by
//! the Jellyfish Merkle Tree. The JMT is a sparse merkle tree that records
//! hashed keys, so we also record an index of the keys themselves to allow
//! range queries on keys rather than key hashes. This index, however, is not
//! part of the verifiable consensus state.
//!
//! * A secondary, non-verifiable key-value store with byte keys and byte
//! values, backed directly by RocksDB. This is intended for use building
//! application-specific indexes of the verifiable consensus state.
//!
//! * A tertiary, in-memory object store. This is intended for use implementing
//! accumulators, like lists of data to be batch-processed at the end of the
//! block. The object store clones on read to prevent violations of
//! transactional semantics, so it should be used with immutable data structures
//! like those in the `im` crate that implement copy-on-write behavior
//! internally.
//!
//! The storage system also supports prefixed "substores", somewhat similar to
//! the Cosmos SDK's multistore design. Each substore has a separate JMT, whose
//! root hash is written into the base store under the prefix. This allows use
//! cases like storing IBC data in a subtree. The substore's non-verifiable
//! store is also stored in a separate RocksDB column family, allowing storage
//! optimizations.
//!
//! Remember that the chain state is a public API. Mapping from raw byte values
//! to typed data should be accomplished by means of extension traits. For
//! instance, the `penumbra_proto` crate provides an extension trait to
//! automatically (de)serialize into proto or domain types, allowing its use as
//! an object store.
//!
//! With the `rpc` feature enabled, this crate also provides a GRPC interface to
//! the key-value store using Tonic.
#![deny(clippy::unwrap_used)]
// Requires nightly.
#![cfg_attr(docsrs, feature(doc_auto_cfg))]
// We use `HashMap`s opportunistically.
#![allow(clippy::disallowed_types)]
mod cache;
mod delta;
mod escaped_byte_slice;
mod metrics;
mod read;
mod snapshot;
mod snapshot_cache;
mod storage;
mod store;
#[cfg(test)]
mod tests;
mod utils;
mod write;
mod write_batch;
#[cfg(feature = "metrics")]
pub use crate::metrics::register_metrics;
pub use cache::Cache;
pub use delta::{ArcStateDeltaExt, StateDelta};
pub use escaped_byte_slice::EscapedByteSlice;
pub use jmt::{ics23_spec, RootHash};
pub use read::StateRead;
pub use snapshot::Snapshot;
pub use storage::{Storage, TempStorage};
pub use write::StateWrite;
pub use write_batch::StagedWriteBatch;
pub mod future;
#[cfg(feature = "rpc")]
pub mod rpc;