-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move trait definitions from
fuel-data
(#1)
Include `Storage` and `MerkleStorage` to be used by `fuel-vm` and `fuel-merkle`. This split is done to not mix the VM types with the merkle tree definitions.
- Loading branch information
Showing
4 changed files
with
189 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
name: Compile and Test | ||
|
||
on: | ||
push: | ||
branches: | ||
- master | ||
tags: | ||
- v* | ||
pull_request: | ||
|
||
env: | ||
CARGO_TERM_COLOR: always | ||
CARGO_NET_GIT_FETCH_WITH_CLI: true | ||
|
||
jobs: | ||
build: | ||
runs-on: ubuntu-latest | ||
|
||
steps: | ||
- name: Checkout repository | ||
uses: actions/checkout@v2 | ||
|
||
- name: Install toolchain | ||
uses: actions-rs/toolchain@v1 | ||
with: | ||
profile: minimal | ||
toolchain: stable | ||
override: true | ||
|
||
- name: Install rustfmt | ||
run: rustup component add rustfmt | ||
|
||
- name: Check formatting | ||
uses: actions-rs/cargo@v1 | ||
with: | ||
command: fmt | ||
args: --all --verbose -- --check | ||
|
||
- name: Build | ||
uses: actions-rs/cargo@v1 | ||
with: | ||
command: build | ||
args: --verbose | ||
|
||
- name: Test | ||
uses: actions-rs/cargo@v1 | ||
with: | ||
command: test | ||
args: --verbose |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
[package] | ||
name = "fuel-storage" | ||
version = "0.1.0" | ||
authors = ["Victor Lopez <victor.lopez@fuel.sh>"] | ||
edition = "2018" | ||
repository = "https://github.com/FuelLabs/fuel-storage" | ||
description = "Storage traits for Fuel storage-backed data structures." | ||
|
||
[dependencies] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
# fuel-storage | ||
# Fuel Storage | ||
|
||
Storage traits for Fuel storage-backed data structures. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
use std::borrow::Cow; | ||
use std::error::Error; | ||
use std::ops::{Deref, DerefMut}; | ||
|
||
/// Merkle root alias type | ||
pub type MerkleRoot = [u8; 32]; | ||
|
||
/// Base map trait for Fuel infrastructure | ||
/// | ||
/// Generics: | ||
/// | ||
/// - K: Key that maps to a value | ||
/// - V: Stored value | ||
pub trait Storage<K, V> | ||
where | ||
V: Clone, | ||
{ | ||
/// Error implementation of the storage functions | ||
type Error: Error; | ||
|
||
/// Append `K->V` mapping to the storage. | ||
/// | ||
/// If `K` was already mappped to a value, return the replaced value as `Ok(Some(V))`. Return | ||
/// `Ok(None)` otherwise. | ||
fn insert(&mut self, key: &K, value: &V) -> Result<Option<V>, Self::Error>; | ||
|
||
/// Remove `K->V` mapping from the storage. | ||
/// | ||
/// Return `Ok(Some(V))` if the value was present. If the key wasn't found, return | ||
/// `Ok(None)`. | ||
fn remove(&mut self, key: &K) -> Result<Option<V>, Self::Error>; | ||
|
||
/// Retrieve `Cow<V>` such as `K->V`. | ||
fn get<'a>(&'a self, key: &K) -> Result<Option<Cow<'a, V>>, Self::Error>; | ||
|
||
/// Return `true` if there is a `K` mapping to a value in the storage. | ||
fn contains_key(&self, key: &K) -> Result<bool, Self::Error>; | ||
} | ||
|
||
impl<K, V, S> Storage<K, V> for &mut S | ||
where | ||
V: Clone, | ||
S: Storage<K, V>, | ||
{ | ||
type Error = S::Error; | ||
|
||
fn insert(&mut self, key: &K, value: &V) -> Result<Option<V>, S::Error> { | ||
<S as Storage<K, V>>::insert(self.deref_mut(), key, value) | ||
} | ||
|
||
fn remove(&mut self, key: &K) -> Result<Option<V>, S::Error> { | ||
<S as Storage<K, V>>::remove(self.deref_mut(), key) | ||
} | ||
|
||
fn get(&self, key: &K) -> Result<Option<Cow<'_, V>>, S::Error> { | ||
<S as Storage<K, V>>::get(self.deref(), key) | ||
} | ||
|
||
fn contains_key(&self, key: &K) -> Result<bool, S::Error> { | ||
<S as Storage<K, V>>::contains_key(self.deref(), key) | ||
} | ||
} | ||
|
||
/// Base trait for Fuel Merkle storage | ||
/// | ||
/// Generics: | ||
/// | ||
/// - P: Domain of the merkle tree | ||
/// - K: Key that maps to a value | ||
/// - V: Stored value | ||
pub trait MerkleStorage<P, K, V> | ||
where | ||
V: Clone, | ||
{ | ||
/// Error implementation of the merkle storage functions | ||
type Error: Error; | ||
|
||
/// Append `P->K->V` mapping to the storage. | ||
/// | ||
/// If `K` was already mappped to a value, return the replaced value as `Ok(Some(V))`. Return | ||
/// `Ok(None)` otherwise. | ||
fn insert(&mut self, parent: &P, key: &K, value: &V) -> Result<Option<V>, Self::Error>; | ||
|
||
/// Remove `P->K->V` mapping from the storage. | ||
/// | ||
/// Return `Ok(Some(V))` if the value was present. If the key wasn't found, return | ||
/// `Ok(None)`. | ||
fn remove(&mut self, parent: &P, key: &K) -> Result<Option<V>, Self::Error>; | ||
|
||
/// Retrieve `Cow<V>` such as `P->K->V`. | ||
fn get<'a>(&'a self, parent: &P, key: &K) -> Result<Option<Cow<'a, V>>, Self::Error>; | ||
|
||
/// Return `true` if there is a `P->K` mapping to a value in the storage. | ||
fn contains_key(&self, parent: &P, key: &K) -> Result<bool, Self::Error>; | ||
|
||
/// Return the merkle root of the domain of `P`. | ||
/// | ||
/// The cryptographic primitive is an arbitrary choice of the implementor and this trait won't | ||
/// impose any restrictions to that. | ||
fn root(&mut self, parent: &P) -> Result<MerkleRoot, Self::Error>; | ||
} | ||
|
||
impl<P, K, V, S> MerkleStorage<P, K, V> for &mut S | ||
where | ||
V: Clone, | ||
S: MerkleStorage<P, K, V>, | ||
{ | ||
type Error = S::Error; | ||
|
||
fn insert(&mut self, parent: &P, key: &K, value: &V) -> Result<Option<V>, S::Error> { | ||
<S as MerkleStorage<P, K, V>>::insert(self.deref_mut(), parent, key, value) | ||
} | ||
|
||
fn remove(&mut self, parent: &P, key: &K) -> Result<Option<V>, S::Error> { | ||
<S as MerkleStorage<P, K, V>>::remove(self.deref_mut(), parent, key) | ||
} | ||
|
||
fn get(&self, parent: &P, key: &K) -> Result<Option<Cow<'_, V>>, S::Error> { | ||
<S as MerkleStorage<P, K, V>>::get(self.deref(), parent, key) | ||
} | ||
|
||
fn contains_key(&self, parent: &P, key: &K) -> Result<bool, S::Error> { | ||
<S as MerkleStorage<P, K, V>>::contains_key(self.deref(), parent, key) | ||
} | ||
|
||
fn root(&mut self, parent: &P) -> Result<MerkleRoot, S::Error> { | ||
<S as MerkleStorage<P, K, V>>::root(self.deref_mut(), parent) | ||
} | ||
} |