Expand description
Interfaces to work with persisted blockchain data. The data can be Merkelized, i.e., stored into authenticated data structures, which allow to prove presence or absence of data with logarithmic overhead.
See also the documentation page on storage.
§Database
A Database is a container for data persistence. Internally, a Database is
a collection of named key-value stores (aka column families)
with reading isolation and atomic writes. The database is assumed to be embedded,
that is, the Exonum process has exclusive access to the DB during blockchain operation.
You can interact with the Database from multiple threads by cloning its instance.
This crate provides two database types: RocksDB and TemporaryDB.
§Snapshot and Fork
Snapshots and forks facilitate access to the database.
If you need to read the data, you can create a Snapshot using the snapshot method
of the Database instance. Snapshots provide read isolation, so you are guaranteed to work
with consistent values even if the data in the database changes between reads. Snapshot
provides all the necessary methods for reading data from the database, so &Snapshot
is used as a storage view for creating a read-only representation of the indexes.
If you need to make changes to the database, you need to create a Fork using
the fork method of the Database. Like Snapshot, Fork provides read isolation,
but also allows creating a sequence of changes to the database that are specified
as a Patch. A patch can be atomically merged into a database. Different threads
may call merge concurrently.
§BinaryKey and BinaryValue traits
If you need to use your own data types as keys or values in the storage, you need to implement
the BinaryKey or BinaryValue traits respectively. These traits have already been
implemented for most standard types.
§Indexes
Indexes are structures representing data collections stored in the database. This concept is similar to tables in relational databases. The interfaces of the indexes are similar to ordinary collections (like arrays, maps and sets).
Each index occupies a certain set of keys in a single column family of the Database.
On the other hand, multiple indexes can be stored in the same column family, provided
that their key spaces do not intersect. Isolation is commonly achieved with the help
of Groups or keyed IndexAddresses.
Merkelized indexes can generate cryptographic proofs about inclusion of entries. Having such a proof, an external client may verify locally that the received data was authorized by the blockchain validators, without having to replicate the entire blockchain contents.
This crate provides the following index types:
Entryis a specific index that stores only one value. Useful for global values, such as configuration. Similar to a combination ofBoxandOption.ListIndexis a list of items stored in a sequential order. Similar toVec.SparseListIndexis a list of items stored in a sequential order. Similar toListIndex, but may contain indexes without elements.MapIndexis a map of keys and values. Similar toBTreeMap.ProofEntryis a Merkelized version ofEntry.ProofListIndexis a Merkelized version ofListIndexthat supports cryptographic proofs of existence and is implemented as a Merkle tree.ProofMapIndexis a Merkelized version ofMapIndexthat supports cryptographic proofs of existence and is implemented as a binary Merkle Patricia tree.KeySetIndexandValueSetIndexare sets of items, similar toBTreeSetandHashSetaccordingly.
§State aggregation
The database automatically aggregates its contents into a single state_hash, which commits
to the entire Merkelized database contents. For example, this is used in Exonum to achieve
consensus as to the database state.
The state_hash of the database is the hash of state_aggregator, a system ProofMapIndex
with keys being UTF-8 names of aggregated indexes, and values their hashes
as per ObjectHash implementation. An index is aggregated if and only if it satisfies
the following constraints:
- Index has a matching type (
ProofListIndex,ProofMapIndex, orProofEntry) - Index is not a part of a group, i.e., its address does not contain the
bytespart
The aggregation is automatically updated when a Fork is converted into a Patch.
Thus, Snapshots (including Patches!) are always consistent with respect
to the aggregated state; the index hashes in the state_aggregator match their actual values.
This is not the case for Forks, in which state_aggregator may be stale.
§Migrations
The database provides tooling for data migrations. With the help of migration, it is possible to gradually accumulate changes to a set of indexes (including across process restarts) and then atomically apply or discard these changes.
Re-exports§
pub use self::indexes::proof_list;pub use self::indexes::proof_list::ListProof;pub use self::indexes::proof_list::ProofListIndex;pub use self::indexes::proof_map;pub use self::indexes::proof_map::MapProof;pub use self::indexes::proof_map::ProofMapIndex;pub use self::indexes::proof_map::RawProofMapIndex;pub use self::indexes::Entry;pub use self::indexes::Group;pub use self::indexes::KeySetIndex;pub use self::indexes::ListIndex;pub use self::indexes::MapIndex;pub use self::indexes::ProofEntry;pub use self::indexes::SparseListIndex;pub use self::indexes::ValueSetIndex;
Modules§
- access
- High-level access to database.
- generic
- Access generalizations, mainly useful for bindings.
- indexes
- All available
MerkleDBindexes. - migration
- Migration utilities.
- validation
- Validation helpers for index names.
Macros§
- impl_
binary_ key_ for_ binary_ value - Implements
BinaryKeytrait for any type that implementsBinaryValue. - impl_
object_ hash_ for_ binary_ value - Implement
ObjectHashtrait for any type that implementsBinaryValue. - impl_
serde_ hex_ for_ binary_ value - Hex conversions for the given
BinaryValue.
Structs§
- DbOptions
- Options for the database.
- Error
- The error type for I/O operations with the
Database. - Fork
- A combination of a database snapshot and changes on top of it.
- Index
Address - Represents the address of an index in the database.
- Lazy
- Lazily initialized object in the database.
- Owned
Readonly Fork - Version of
ReadonlyForkwith a static lifetime. Can be produced from anRc<Fork>using theAsReadonlytrait. - Patch
- A set of changes that can be atomically applied to a
Database. - Readonly
Fork - Readonly wrapper for a
Fork. - Resolved
Address - Resolved address of a view.
- RocksDB
- Database implementation on top of
RocksDBbackend. - System
Schema - System-wide information about the database.
- TemporaryDB
- A wrapper over the
RocksDBbackend which stores data in the temporary directory using thetempfilecrate.
Enums§
- HashTag
- Prefixes for different types of objects stored in the database. These prefixes are necessary to provide domain separation among hashed objects of different types.
- Index
Type - Type of an index supported by Exonum.
- Validation
Error - Errors that can occur while validating a
ListProoforMapProofagainst a trusted collection hash.
Traits§
- AsReadonly
- Converts index access to a readonly presentation. The conversion operation is cheap.
- Binary
Key - A type that can be (de)serialized as a key in the blockchain storage.
- Binary
Value - A type that can be (de)serialized as a value in the blockchain storage.
- Database
- Low-level storage backend implementing a collection of named key-value stores (aka column families).
- Database
Ext - Extension trait for
Database. - Iterator
- A trait that defines a streaming iterator over storage view entries. Unlike
the standard
Iteratortrait,Iteratorin Exonum is low-level and, therefore, operates with bytes. - Object
Hash - A common trait for the ability to compute a unique hash.
- Snapshot
- A read-only snapshot of a storage backend.
Functions§
- root_
hash - Computes a Merkle root hash for a the given list of hashes.