Просмотр исходного кода

blockchain: Implement StateStore.

Luther Blissett 3 лет назад
Родитель
Сommit
3baa7caddb
2 измененных файлов с 46 добавлено и 0 удалено
  1. 3 0
      src/blockchain/mod.rs
  2. 43 0
      src/blockchain/statestore.rs

+ 3 - 0
src/blockchain/mod.rs

@@ -21,6 +21,9 @@ pub use nfstore::NullifierStore;
 pub mod rootstore;
 pub use rootstore::RootStore;
 
+pub mod statestore;
+pub use statestore::StateStore;
+
 pub mod txstore;
 pub use txstore::TxStore;
 

+ 43 - 0
src/blockchain/statestore.rs

@@ -0,0 +1,43 @@
+use crate::{crypto::contract_id::ContractId, serial::serialize, Result};
+
+const SLED_STATES_TREE: &[u8] = b"_states";
+
+/// The `StateStore` is a `sled` tree storing states of deployed contracts.
+/// The states themselves are data that is allocated and stored as raw bytes.
+/// These bytes are (de)serialized by the code in wasm and the contracts can
+/// operate on the state data themselves. Regarding on the (byte) size of the
+/// state, the contract deployer should allocate and pay for a certain size of
+/// their state stored by all the nodes. The cost should be linear to the byte
+/// size used.
+#[derive(Clone)]
+pub struct StateStore(sled::Tree);
+
+impl StateStore {
+    /// Opens a new or existing `StateStore` on the given sled database.
+    pub fn new(db: &sled::Db) -> Result<Self> {
+        let tree = db.open_tree(SLED_STATES_TREE)?;
+        Ok(Self(tree))
+    }
+
+    /// Insert a state into the store. This will replace the previous state.
+    /// The contract's ID is used as a key, while the value is the contract
+    /// state serialized to bytes.
+    pub fn insert(&self, contract_id: &ContractId, contract_state: &[u8]) -> Result<()> {
+        self.0.insert(serialize(contract_id), contract_state.to_vec())?;
+        Ok(())
+    }
+
+    /// Check if the `StateStore` contains a state for the given `ContractId`.
+    pub fn contains(&self, contract_id: &ContractId) -> Result<bool> {
+        Ok(self.0.contains_key(serialize(contract_id))?)
+    }
+
+    /// Retrieve a state from the `StateStore` given a `ContractId` if it exists.
+    pub fn get(&self, contract_id: &ContractId) -> Result<Option<Vec<u8>>> {
+        if let Some(data) = self.0.get(serialize(contract_id))? {
+            return Ok(Some(data.to_vec()))
+        }
+
+        Ok(None)
+    }
+}