//! Traits representing the 4 possible states of an Any database. These are used to share test and //! benchmark code across the variants. use crate::{ kv::{Batchable, Deletable, Gettable}, mmr::Location, qmdb::{ store::{LogStore, MerkleizedStore, PrunableStore}, Error, }, Persistable, }; use commonware_codec::Codec; use commonware_cryptography::Digest; use commonware_utils::Array; use std::{future::Future, ops::Range}; /// Trait for the (Merkleized,Durable) state. /// /// This state allows authentication (root, proofs), pruning, and persistence operations /// (sync/close/destroy). Use `into_mutable` to transition to the (Unmerkleized,Non-durable) state. pub trait CleanAny: MerkleizedStore + PrunableStore + Persistable + Gettable::Value, Error = Error> { /// The mutable state type (Unmerkleized,Non-durable). type Mutable: MutableAny< Key = Self::Key, Digest = ::Digest, Operation = ::Operation, // Cycle constraint for path: commit() then into_merkleized() or into_mutable() Durable: UnmerkleizedDurableAny, > + LogStore::Value>; /// Convert this database into the mutable (Unmerkleized, Non-durable) state. fn into_mutable(self) -> Self::Mutable; } /// Trait for the (Unmerkleized,Durable) state. /// /// Use `into_mutable` to transition to the (Unmerkleized,NonDurable) state, or `into_merkleized` to /// transition to the (Merkleized,Durable) state. pub trait UnmerkleizedDurableAny: LogStore + Gettable::Value, Error = Error> { /// The digest type used by Merkleized states in this database's state machine. type Digest: Digest; /// The operation type used by Merkleized states in this database's state machine. type Operation: Codec; /// The mutable state type (Unmerkleized,NonDurable). type Mutable: MutableAny + LogStore::Value>; /// The provable state type (Merkleized,Durable). type Merkleized: CleanAny + MerkleizedStore< Value = ::Value, Digest = Self::Digest, Operation = Self::Operation, >; /// Convert this database into the mutable state. fn into_mutable(self) -> Self::Mutable; /// Convert this database into the provable (Merkleized,Durable) state. fn into_merkleized(self) -> impl Future> + Send; } /// Trait for the (Merkleized,NonDurable) state. /// /// This state allows authentication (root, proofs) and pruning. Use `commit` to transition to the /// Merkleized, Durable state. pub trait MerkleizedNonDurableAny: MerkleizedStore + PrunableStore + Gettable::Value, Error = Error> { /// The mutable state type (Unmerkleized,NonDurable). type Mutable: MutableAny; /// Convert this database into the mutable (Unmerkleized, NonDurable) state. fn into_mutable(self) -> Self::Mutable; } /// Trait for the (Unmerkleized,NonDurable) state. /// /// This is the only state that allows mutations (create/update/delete). Use `commit` to transition /// to the Unmerkleized, Durable state, or `into_merkleized` to transition to the Merkleized, /// NonDurable state. pub trait MutableAny: LogStore + Deletable::Value, Error = Error> + Batchable { /// The digest type used by Merkleized states in this database's state machine. type Digest: Digest; /// The operation type used by Merkleized states in this database's state machine. type Operation: Codec; /// The durable state type (Unmerkleized,Durable). type Durable: UnmerkleizedDurableAny + LogStore::Value>; /// The provable state type (Merkleized,NonDurable). type Merkleized: MerkleizedNonDurableAny + MerkleizedStore< Value = ::Value, Digest = Self::Digest, Operation = Self::Operation, >; /// Commit any pending operations to the database, ensuring their durability. Returns the db in /// its durable state and the location range of committed operations. Note that even if no /// operations were added since the last commit, this a root-state changing operation. fn commit( self, metadata: Option<::Value>, ) -> impl Future), Error>> + Send; /// Convert this database into the provable (Merkleized, Non-durable) state. fn into_merkleized(self) -> impl Future> + Send; /// Returns the number of steps to raise the inactivity floor on the next commit. fn steps(&self) -> u64; }