pub trait BlockStore:
Debug
+ Send
+ Sync {
// Required methods
fn node_id(&self) -> &str;
fn list_ring_ids(&self) -> StoreResult<Vec<(String, u64)>>;
fn get_ring(&self, ring_id: &str) -> StoreResult<(u64, ZeroingWords)>;
fn store_ring(
&self,
ring_id: &str,
version: u64,
raw: &[u8],
) -> StoreResult<()>;
fn change_logs(&self) -> StoreResult<Vec<ChangeLog>>;
fn get_index(&self, index_id: &str) -> StoreResult<Option<ZeroingWords>>;
fn store_index(&self, index_id: &str, raw: &[u8]) -> StoreResult<()>;
fn add_block(&self, raw: &[u8]) -> StoreResult<String>;
fn get_block(&self, block: &str) -> StoreResult<ZeroingWords>;
fn commit(&self, changes: &[Change]) -> StoreResult<()>;
fn update_change_log(&self, change_log: ChangeLog) -> StoreResult<()>;
}
Expand description
Common interface of all block stores
In terms of persistence t-rust-less thinks in collections of blocks. Whereas a
block is just a chunk of bytes (i.e. Vec
To put it even more bluntly: All data inside a block has to be protected in a way that the underlying medium might as well be twitter or facebook (not that I actually suggest or plan to write an implementation of that sort). The blcok store in itself is not responsible providing this sort of protection … is just stores and organizes blocks.
As a rule a block store is supposed to be distributed among multiple clients, each able to asynchronously create additions to it.
All implementation are supposed to be thread-safe. Any kind of internal state has to be protected accordingly.
Required Methods§
Sourcefn node_id(&self) -> &str
fn node_id(&self) -> &str
Get the current node id.
Each accessor to a distributed store should have a unique id.
Sourcefn list_ring_ids(&self) -> StoreResult<Vec<(String, u64)>>
fn list_ring_ids(&self) -> StoreResult<Vec<(String, u64)>>
Get list of ring block identifiers.
A store may contain any number of secrets rings. Usually associated with identities/users that may access the store.
Sourcefn get_ring(&self, ring_id: &str) -> StoreResult<(u64, ZeroingWords)>
fn get_ring(&self, ring_id: &str) -> StoreResult<(u64, ZeroingWords)>
Get/read the ring block by its id.
Every identities/user should have a ring block containing all the relevant key material to encrypt/descript all the other blocks.
Theses block should be protected by some sort of passphrase/key-derivation
Sourcefn store_ring(&self, ring_id: &str, version: u64, raw: &[u8]) -> StoreResult<()>
fn store_ring(&self, ring_id: &str, version: u64, raw: &[u8]) -> StoreResult<()>
Set/write a ring block.
Implementors should ensure a sort of backup in case this operation fails, since loosing the (private) ring will render the entire store useless to a user
Sourcefn change_logs(&self) -> StoreResult<Vec<ChangeLog>>
fn change_logs(&self) -> StoreResult<Vec<ChangeLog>>
Get all the change logs of the store.
The store has to keep track of all commits (see below).
Sourcefn get_index(&self, index_id: &str) -> StoreResult<Option<ZeroingWords>>
fn get_index(&self, index_id: &str) -> StoreResult<Option<ZeroingWords>>
Get the index block of a specific client/user.
An index block contains any sort of searchable index data referencing the underlying data blocks. As the index might contain sensible data this block has to be protected similar to a regular data block.
Index blocks should not be shared among clients or user. I.e. every client/user should have its own set index blocks.
Sourcefn store_index(&self, index_id: &str, raw: &[u8]) -> StoreResult<()>
fn store_index(&self, index_id: &str, raw: &[u8]) -> StoreResult<()>
Store the index block of a specific client/user.
Sourcefn add_block(&self, raw: &[u8]) -> StoreResult<String>
fn add_block(&self, raw: &[u8]) -> StoreResult<String>
Add a new data block to the store.
Data blocks contain the secret data shared between clients and should be protected by the keys inside the ring block.
The result of an add operation is a unique key of the data block.
Sourcefn get_block(&self, block: &str) -> StoreResult<ZeroingWords>
fn get_block(&self, block: &str) -> StoreResult<ZeroingWords>
Get a block by its id.
Sourcefn commit(&self, changes: &[Change]) -> StoreResult<()>
fn commit(&self, changes: &[Change]) -> StoreResult<()>
Commit a set of changes to the store.
After adding one or more blocks to the store every client has to
commit its changes. This will create an entry in the change_log
so that
other clients will notice the new data blocks.
Sourcefn update_change_log(&self, change_log: ChangeLog) -> StoreResult<()>
fn update_change_log(&self, change_log: ChangeLog) -> StoreResult<()>
Update changelog of other nodes.
This is intended for store synchronization only.