Skip to content

Commit

Permalink
Add missing docs to sov-state (#841)
Browse files Browse the repository at this point in the history
* #![deny(missing_docs)]

* More docs

Signed-off-by: Filippo Costa <[email protected]>

* Fix doc link

Signed-off-by: Filippo Costa <[email protected]>

* Fix docs

Signed-off-by: Filippo Costa <[email protected]>

* Fix doc

Signed-off-by: Filippo Costa <[email protected]>

* Fix doc

Signed-off-by: Filippo Costa <[email protected]>

---------

Signed-off-by: Filippo Costa <[email protected]>
  • Loading branch information
neysofu authored Sep 15, 2023
1 parent c2206ff commit a94c333
Show file tree
Hide file tree
Showing 20 changed files with 236 additions and 48 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions module-system/sov-state/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ risc0-zkvm-platform = { workspace = true, optional = true }

[dev-dependencies]
tempfile = { workspace = true }
proptest = { workspace = true }

[features]
bench = ["sov-zk-cycle-macros", "risc0-zkvm", "risc0-zkvm-platform"]
Expand Down
3 changes: 2 additions & 1 deletion module-system/sov-state/src/codec/bcs_codec.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::{StateCodec, StateKeyCodec};
use crate::codec::StateValueCodec;

/// A [`StateValueCodec`] that uses [`bcs`] for all keys and values.
/// A [`StateCodec`] that uses [`bcs`] for all keys and values.
#[derive(Debug, Default, PartialEq, Eq, Clone, serde::Serialize, serde::Deserialize)]
pub struct BcsCodec;

Expand Down Expand Up @@ -32,6 +32,7 @@ where
impl StateCodec for BcsCodec {
type KeyCodec = Self;
type ValueCodec = Self;

fn key_codec(&self) -> &Self::KeyCodec {
self
}
Expand Down
5 changes: 3 additions & 2 deletions module-system/sov-state/src/codec/borsh_codec.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use super::{StateCodec, StateKeyCodec};
use crate::codec::StateValueCodec;

/// A [`StateValueCodec`] that uses [`borsh`] for all values.
/// A [`StateCodec`] that uses [`borsh`] for all keys and values.
#[derive(Debug, Default, PartialEq, Eq, Clone, borsh::BorshDeserialize, borsh::BorshSerialize)]
pub struct BorshCodec;

Expand All @@ -10,7 +10,7 @@ where
K: borsh::BorshSerialize + borsh::BorshDeserialize,
{
fn encode_key(&self, value: &K) -> Vec<u8> {
value.try_to_vec().expect("Failed to serialize value")
value.try_to_vec().expect("Failed to serialize key")
}
}

Expand All @@ -32,6 +32,7 @@ where
impl StateCodec for BorshCodec {
type KeyCodec = Self;
type ValueCodec = Self;

fn key_codec(&self) -> &Self::KeyCodec {
self
}
Expand Down
4 changes: 2 additions & 2 deletions module-system/sov-state/src/codec/json_codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use serde_json;
use super::{StateCodec, StateKeyCodec};
use crate::codec::StateValueCodec;

/// A [`StateValueCodec`] that uses [`serde_json`] for all values.
/// A [`StateCodec`] that uses [`serde_json`] for all keys and values.
#[derive(Debug, Default, PartialEq, Eq, Clone, serde::Serialize, serde::Deserialize)]
pub struct JsonCodec;

Expand All @@ -12,7 +12,7 @@ where
K: serde::Serialize,
{
fn encode_key(&self, key: &K) -> Vec<u8> {
serde_json::to_vec(key).expect("Failed to serialize value")
serde_json::to_vec(key).expect("Failed to serialize key")
}
}

Expand Down
61 changes: 48 additions & 13 deletions module-system/sov-state/src/codec/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,21 +47,43 @@ pub trait StateValueCodec<V> {

/// A trait for types that can serialize keys for storage
/// access.
///
/// Note that, unlike [`StateValueCodec`], this trait does not provide
/// deserialization logic as it's not needed nor supported.
pub trait StateKeyCodec<K> {
/// Serializes a key into a bytes vector.
///
/// # Determinism
///
/// All implementations of this trait method **MUST** provide deterministic
/// serialization behavior:
///
/// 1. Equal (as defined by [`Eq`]) values **MUST** be serialized to the same
/// byte sequence.
/// 2. The serialization result **MUST NOT** depend on the compilation target
/// and other runtime environment parameters. If that were the case, zkVM
/// code and native code wouldn't produce the same keys.
fn encode_key(&self, key: &K) -> Vec<u8>;
}

/// A trait for types that can serialize keys and values, as well
/// as deserializing values for storage access.
///
/// # Type bounds
/// There are no type bounds on [`StateCodec::KeyCodec`] and
/// [`StateCodec::ValueCodec`], so they can be any type at well. That said,
/// you'll find many APIs require these two to implement [`StateKeyCodec`] and
/// [`StateValueCodec`] respectively.
pub trait StateCodec {
/// The codec used to serialize keys
/// The codec used to serialize keys. See [`StateKeyCodec`].
type KeyCodec;
/// The codec used to serialize and deserialize values
/// The codec used to serialize and deserialize values. See
/// [`StateValueCodec`].
type ValueCodec;

/// Returns a reference to the type's key codec
/// Returns a reference to the type's key codec.
fn key_codec(&self) -> &Self::KeyCodec;
/// Returns a reference to the type's value codec
/// Returns a reference to the type's value codec.
fn value_codec(&self) -> &Self::ValueCodec;
}

Expand Down Expand Up @@ -97,13 +119,26 @@ where
}
}

#[test]
fn test_borsh_slice_encode_alike() {
let codec = BorshCodec;
let slice = [1, 2, 3];
let vec = vec![1, 2, 3];
assert_eq!(
<BorshCodec as EncodeKeyLike<[i32], Vec<i32>>>::encode_key_like(&codec, &slice),
codec.encode_value(&vec)
);
#[cfg(test)]
mod tests {
use proptest::collection::vec;
use proptest::prelude::any;
use proptest::strategy::Strategy;

use super::*;

fn arb_vec_i32() -> impl Strategy<Value = Vec<i32>> {
vec(any::<i32>(), 0..2048)
}

proptest::proptest! {
#[test]
fn test_borsh_slice_encode_alike(vec in arb_vec_i32()) {
let codec = BorshCodec;
assert_eq!(
<BorshCodec as EncodeKeyLike<[i32], Vec<i32>>>::encode_key_like(&codec, &vec[..]),
codec.encode_value(&vec)
);
}
}
}
3 changes: 3 additions & 0 deletions module-system/sov-state/src/codec/split_codec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ use super::{StateCodec, StateKeyCodec, StateValueCodec};
/// A [`StateValueCodec`] that uses one pre-existing codec for keys and a different one values.
#[derive(Debug, Default, PartialEq, Eq, Clone)]
pub struct SplitCodec<KC, VC> {
/// The codec to use for keys.
pub key_codec: KC,
/// The codec to use for values.
pub value_codec: VC,
}

Expand Down Expand Up @@ -36,6 +38,7 @@ where
impl<KC, VC> StateCodec for SplitCodec<KC, VC> {
type KeyCodec = KC;
type ValueCodec = VC;

fn key_codec(&self) -> &Self::KeyCodec {
&self.key_codec
}
Expand Down
6 changes: 5 additions & 1 deletion module-system/sov-state/src/config.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
//! Configuration options for [`Storage`](crate::storage::Storage) types.
use std::path::PathBuf;

/// Configuration options for [`ProverStorage`](crate::ProverStorage)
/// initialization.
#[derive(serde::Deserialize, Debug, Clone, PartialEq, Eq)]
pub struct Config {
/// Path to folder where storage files will be stored
/// Path to folder where storage files will be stored.
pub path: PathBuf,
}
3 changes: 3 additions & 0 deletions module-system/sov-state/src/containers/accessory_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,9 @@ where
Codec::KeyCodec: StateKeyCodec<K>,
Codec::ValueCodec: StateValueCodec<V>,
{
/// Generates an arbitrary [`AccessoryStateMap`] instance.
///
/// See the [`arbitrary`] crate for more information.
pub fn arbitrary_workset<S>(
u: &mut arbitrary::Unstructured<'a>,
working_set: &mut AccessoryWorkingSet<S>,
Expand Down
13 changes: 7 additions & 6 deletions module-system/sov-state/src/containers/accessory_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ use crate::{
AccessoryStateMap, AccessoryStateValue, AccessoryWorkingSet, Prefix, StateVecError, Storage,
};

/// A variant of [`StateVec`](crate::StateVec) that stores its elements as
/// "accessory" state, instead of in the JMT.
#[derive(
Debug,
Clone,
Expand Down Expand Up @@ -139,6 +141,7 @@ where
Some(elem)
}

/// Removes all values from this [`AccessoryStateVec`].
pub fn clear<S: Storage>(&self, working_set: &mut AccessoryWorkingSet<S>) {
let len = self.len_value.remove(working_set).unwrap_or_default();

Expand Down Expand Up @@ -180,14 +183,12 @@ where
}
}

/// Returns the last value in the [`AccessoryStateVec`], or [`None`] if
/// empty.
pub fn last<S: Storage>(&self, working_set: &mut AccessoryWorkingSet<S>) -> Option<V> {
let len = self.len(working_set);

if len == 0usize {
None
} else {
self.elems.get(&(len - 1), working_set)
}
let i = len.checked_sub(1)?;
self.elems.get(&i, working_set)
}
}

Expand Down
5 changes: 5 additions & 0 deletions module-system/sov-state/src/containers/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ pub struct StateMap<K, V, Codec = BorshCodec> {
/// Error type for the [`StateMap::get`] method.
#[derive(Debug, Error)]
pub enum StateMapError {
/// Value not found.
#[error("Value not found for prefix: {0} and: storage key {1}")]
MissingValue(Prefix, StorageKey),
}
Expand All @@ -53,6 +54,7 @@ impl<K, V, Codec> StateMap<K, V, Codec> {
}
}

/// Returns a reference to the codec used by this [`StateMap`].
pub fn codec(&self) -> &Codec {
&self.codec
}
Expand Down Expand Up @@ -206,6 +208,9 @@ where
Codec::KeyCodec: StateKeyCodec<K>,
Codec::ValueCodec: StateValueCodec<V>,
{
/// Returns an arbitrary [`StateMap`] instance.
///
/// See the [`arbitrary`] crate for more information.
pub fn arbitrary_workset<S>(
u: &mut arbitrary::Unstructured<'a>,
working_set: &mut WorkingSet<S>,
Expand Down
1 change: 1 addition & 0 deletions module-system/sov-state/src/containers/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ pub struct StateValue<V, Codec = BorshCodec> {
/// Error type for `StateValue` get method.
#[derive(Debug, Error)]
pub enum Error {
/// Value not found.
#[error("Value not found for prefix: {0}")]
MissingValue(Prefix),
}
Expand Down
16 changes: 9 additions & 7 deletions module-system/sov-state/src/containers/vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ use thiserror::Error;
use crate::codec::{BorshCodec, StateCodec, StateKeyCodec, StateValueCodec};
use crate::{Prefix, StateMap, StateValue, Storage, WorkingSet};

/// A growable array of values stored as JMT-backed state.
#[derive(
Debug,
Clone,
Expand All @@ -25,8 +26,10 @@ pub struct StateVec<V, Codec = BorshCodec> {
/// Error type for `StateVec` get method.
#[derive(Debug, Error)]
pub enum Error {
/// Operation failed because the index was out of bounds.
#[error("Index out of bounds for index: {0}")]
IndexOutOfBounds(usize),
/// Value not found.
#[error("Value not found for prefix: {0} and index: {1}")]
MissingValue(Prefix, usize),
}
Expand Down Expand Up @@ -141,6 +144,7 @@ where
Some(elem)
}

/// Removes all values from this [`StateVec`].
pub fn clear<S: Storage>(&self, working_set: &mut WorkingSet<S>) {
let len = self.len_value.remove(working_set).unwrap_or_default();

Expand Down Expand Up @@ -182,18 +186,16 @@ where
}
}

/// Returns the last value in the [`StateVec`], or [`None`] if
/// empty.
pub fn last<S: Storage>(&self, working_set: &mut WorkingSet<S>) -> Option<V> {
let len = self.len(working_set);

if len == 0usize {
None
} else {
self.elems.get(&(len - 1), working_set)
}
let i = len.checked_sub(1)?;
self.elems.get(&i, working_set)
}
}

/// An [`Iterator`] over a [`StateVec`]
/// An [`Iterator`] over a [`StateVec`].
///
/// See [`StateVec::iter`] for more details.
pub struct StateVecIter<'a, 'ws, V, Codec, S>
Expand Down
Loading

0 comments on commit a94c333

Please sign in to comment.