use crate::{
index::Unordered as UnorderedIndex,
journal::contiguous::{Contiguous, Mutable},
merkle::{self, Location},
qmdb::{
any::{
operation::update::Unordered as UnorderedUpdate,
unordered::{Operation, Update},
ValueEncoding,
},
current::proof::OperationProof,
Error,
},
Context,
};
use commonware_codec::Codec;
use commonware_cryptography::Hasher;
use commonware_utils::Array;
pub type KeyValueProof<F, D, const N: usize> = OperationProof<F, D, N>;
pub type Db<F, E, C, K, V, I, H, const N: usize> =
crate::qmdb::current::db::Db<F, E, C, I, H, Update<K, V>, N>;
impl<
F: merkle::Graftable,
E: Context,
C: Contiguous<Item = Operation<F, K, V>>,
K: Array,
V: ValueEncoding,
I: UnorderedIndex<Value = Location<F>>,
H: Hasher,
const N: usize,
> Db<F, E, C, K, V, I, H, N>
where
Operation<F, K, V>: Codec,
{
pub async fn get(&self, key: &K) -> Result<Option<V::Value>, Error<F>> {
self.any.get(key).await
}
pub fn verify_key_value_proof(
hasher: &mut H,
key: K,
value: V::Value,
proof: &KeyValueProof<F, H::Digest, N>,
root: &H::Digest,
) -> bool {
let op = Operation::Update(UnorderedUpdate(key, value));
proof.verify(hasher, op, root)
}
}
impl<
F: merkle::Graftable,
E: Context,
C: Mutable<Item = Operation<F, K, V>>,
K: Array,
V: ValueEncoding,
I: UnorderedIndex<Value = Location<F>>,
H: Hasher,
const N: usize,
> Db<F, E, C, K, V, I, H, N>
where
Operation<F, K, V>: Codec,
{
pub async fn key_value_proof(
&self,
hasher: &mut H,
key: K,
) -> Result<KeyValueProof<F, H::Digest, N>, Error<F>> {
let op_loc = self.any.get_with_loc(&key).await?;
let Some((_, loc)) = op_loc else {
return Err(Error::<F>::KeyNotFound);
};
self.operation_proof(hasher, loc).await
}
}