3个版本 (重大更新)
0.3.0 | 2023年10月20日 |
---|---|
0.2.0 | 2023年9月14日 |
0.1.0 | 2023年5月31日 |
#50 in #sovereign
每月 124 次下载
在 11 个 crate 中使用 (10 直接)
185KB
3.5K SLoC
sov-state
此crate提供特定于从永久存储中存储和检索数据的抽象,适用于在模块系统中使用。
高级说明
从高层次来看,该crate提供了两个主要抽象,模块开发者可以利用这些抽象来访问数据
StateValue
:用于在状态中存储单个值。它提供设置值和稍后检索值的方法。StateMap
:用于在状态中存储映射。它允许模块开发者将键与值相关联,并相应地检索它们。
未来,此crate旨在引入其他抽象,如StateVec
,以进一步增强模块系统中的数据存储功能。
以下是一个展示StateValue
API一部分的代码片段
impl StateValue<V> {
/// Sets a value in the StateValue.
pub fn set<S: Storage>(&self, value: V, working_set: &mut WorkingSet<S>) {
// Implementation details
}
/// Gets a value from the StateValue or None if the value is absent.
pub fn get<S: Storage>(&self, working_set: &mut WorkingSet<S>) -> Option<V> {
// Implementation details
}
// Additional methods
// ...
}
get
和 set
方法都需要一个 WorkingSet
参数,它是一个包装在具有附加缓存层的 键值存储
上的封装器。
模块开发者可以与 WorkingSet
、StateValue
和 StateMap
交互,无需担心这些组件的内部工作原理。相反,他们可以将它们视为处理数据存储和检索的“黑盒”。
以上API的使用方式如下
state.value.set(&some_value, working_set);
let maybe_value = state.value.get(working_set);
低级说明
需要注意的是,理解本节内容对于高效使用sov-state
并非必需。
Native
& Zkp
执行
在 Native
执行过程中,数据存储在 键值
存储中,通过 WorkingSet
访问。值得一提的是,实际的存储机制,如 RocksDB
,仅在完整节点执行事务并更新状态的这个阶段才能访问。
相比之下,在 Zkp
阶段,当生成正确执行的加密证明时,模块系统无法直接访问底层数据库。相反,它依赖于 Native
执行期间产生的“见证”。系统通过使用梅克尔树(Merkle trees)等变体进行加密检查,以验证状态是否正确更新。尽管访问存储机制的方式不同,但两种场景都可以通过相同的接口进行抽象。
Storage
抽象定义为以下内容
pub trait Storage: Clone {
type Witness: Witness;
/// The runtime config for this storage instance.
type RuntimeConfig;
fn with_config(config: Self::RuntimeConfig) -> Result<Self, anyhow::Error>;
/// Returns the value corresponding to the key or None if key is absent.
fn get(&self, key: StorageKey, witness: &Self::Witness) -> Option<StorageValue>;
/// Validate all of the storage accesses in a particular cache log,
/// returning the new state root after applying all writes
fn validate_and_commit(
&self,
state_accesses: OrderedReadsAndWrites,
witness: &Self::Witness,
) -> Result<[u8; 32], anyhow::Error>;
}
sov-state
包提供了 Storage 特性的两种实现:ZkStorage
和 ProverStorage
。这些实现分别处理 Zkp
和 Native
执行模式下的数据存储和检索。为了在 zk-proof 生成不是问题的情况下提高性能,可以添加一个额外的实现,该实现不包括生成见证。这些实现封装了所需的逻辑和与存储系统的交互,使得模块开发者可以在不同的执行模式下使用一致的接口。
WorkingSet
:
执行状态更新和生成见证是一个耗时的过程。因此,引入缓存层以减轻这些问题是合理的。《WorkingSet》将数据写入内存映射,仅在数据不在映射中时才从后端存储读取。有关我们缓存的信息,请参阅 sov-first-read-last-write-cache
包。此外,缓存简化了状态回滚的实现过程。如果在特定事务需要回滚的情况下,我们只需简单地丢弃相关缓存中进行的所有写入即可。
依赖项
~6–22MB
~319K SLoC