Skip to content
This repository has been archived by the owner on Aug 14, 2023. It is now read-only.

Commit

Permalink
Global State: versioned KV store with root signature calculation (#333)
Browse files Browse the repository at this point in the history
  • Loading branch information
neysofu authored Aug 19, 2021
1 parent f8b6678 commit 87f892d
Show file tree
Hide file tree
Showing 13 changed files with 1,817 additions and 44 deletions.
1,002 changes: 985 additions & 17 deletions Cargo.lock

Large diffs are not rendered by default.

12 changes: 7 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,6 @@ include = ["README.md", "LICENSE", "Cargo.toml", "Cargo.lock"]
crate-type = ["cdylib", "staticlib", "rlib"]

[dependencies]
thiserror = "1"
seq-macro = "0.2"
tiny-keccak = "1.4.2"
wasmer = { version = "2", default-features = false, optional = true }
wee_alloc = { version = "0.4.5", optional = true }
byteorder = "1.3.2"
cfg-if = "1.0"
clap = "2.33"
Expand All @@ -30,6 +25,7 @@ log = "0.4"
indexmap = "1.6.2"
parity-wasm = "0.42.2"
# rocksdb = { version = "0.15.0", features = ["lz4"], default-features = false, optional = true }
seq-macro = "0.2"
svm-cli = { path = "crates/cli" }
svm-hash = { path = "crates/hash" }
svm-kv = { path = "crates/kv", default-features = false }
Expand All @@ -50,8 +46,14 @@ svm-program = { path = "crates/program" }
svm-storage = { path = "crates/storage", default-features = false }
svm-runtime = { path = "crates/runtime", default-features = false }
svm-runtime-ffi = { path = "crates/runtime-ffi", default-features = false }
svm-state = { path = "crates/state", default-features = false }
svm-abi-layout = { path = "crates/abi/layout" }
svm-abi-tests = { path = "crates/abi/tests" }
thiserror = "1"
tracing = "0.1"
tracing-subscriber = "0.2"
wasmer = { version = "2", default-features = false, optional = true }
wee_alloc = { version = "0.4.5", optional = true }

[build-dependencies]
cbindgen = "0.19.0"
Expand Down
2 changes: 1 addition & 1 deletion crates/hash/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,4 @@ description = "Spacemesh Virtual Machine"
publish = false

[dependencies]
tiny-keccak = "1.4.2"
blake3 = "1"
54 changes: 42 additions & 12 deletions crates/hash/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,57 @@
//! A [`Hasher`] trait for wide-digest algorithms and its [`DefaultHasher`]
//! implementation.
use tiny_keccak::Keccak;
#![deny(missing_docs)]
#![deny(unused)]
#![deny(dead_code)]
#![deny(unreachable_code)]

/// A low-level trait for defining a hasher.
pub trait Hasher {
pub trait Hasher: Default {
/// `KeyHasher` produces hashes of type `Self::Hash`
type Hash: AsRef<[u8]> + Copy + Clone + std::fmt::Debug + Sized;
type Hash: AsRef<[u8]> + Copy + std::fmt::Debug + Sized;

/// Receives an input `key` and returns its hash as `Self::Hash`
fn hash(key: &[u8]) -> Self::Hash;
/// Receives an input `key` and returns its hash as `Self::Hash`.
fn hash(key: &[u8]) -> Self::Hash {
let mut hasher = Self::default();
hasher.update(key);
hasher.finalize()
}

/// Writes some arbitrary `bytes` into this [`Hasher`].
fn update(&mut self, bytes: &[u8]) -> &mut Self;

/// Returns the final [`Hasher::Hash`] value for all data written to `self`
/// via [`Hasher::update`] so far.
fn finalize(self) -> Self::Hash;
}

/// Implements the `KeyHasher` trait using the `keccak256` hashing algorithm (output: 32 bytes)
pub struct DefaultHasher;
/// Implements the [`Hasher`] trait using the Blake3 hashing algorithm (output:
/// 32 bytes).
#[derive(Clone, Debug, Default)]
pub struct Blake3Hasher(blake3::Hasher);

impl std::hash::Hasher for Blake3Hasher {
fn write(&mut self, bytes: &[u8]) {
self.0.update(bytes);
}

impl Hasher for DefaultHasher {
fn finish(&self) -> u64 {
let mut hash = [0; 8];
self.0.finalize_xof().fill(&mut hash);
u64::from_be_bytes(hash)
}
}

impl Hasher for Blake3Hasher {
type Hash = [u8; 32];

fn hash(key: &[u8]) -> Self::Hash {
let mut out = [0; 32];
fn update(&mut self, bytes: &[u8]) -> &mut Self {
self.0.update(bytes);
self
}

Keccak::keccak256(key, &mut out);
out
fn finalize(self) -> Self::Hash {
*self.0.finalize().as_bytes()
}
}
1 change: 1 addition & 0 deletions crates/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ svm-hash = { path = "../hash" }
svm-types = { path = "../types" }
svm-layout = { path = "../layout" }
svm-kv = { path = "../kv", default-features = false }
svm-state = { path = "../state" }
svm-storage = { path = "../storage", default-features = false }
svm-codec = { path = "../codec" }
svm-gas = { path = "../gas" }
Expand Down
6 changes: 3 additions & 3 deletions crates/runtime/src/env/default/address_compute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use crate::env::{self, traits};
use env::{ExtSpawn, Template};
use traits::ComputeAddress;

use svm_hash::{DefaultHasher, Hasher};
use svm_hash::{Blake3Hasher, Hasher};
use svm_types::{Address, TemplateAddr};

/// Default implementation for computing an `Account's Address` deterministically.
Expand All @@ -21,7 +21,7 @@ impl ComputeAddress<Template> for DefaultTemplateAddressCompute {

buf.extend_from_slice(template.code());

let hash = DefaultHasher::hash(&buf);
let hash = Blake3Hasher::hash(&buf);
let addr = TemplateAddr::from(&hash[0..TemplateAddr::len()]);

addr
Expand All @@ -40,7 +40,7 @@ impl ComputeAddress<ExtSpawn> for DefaultAccountAddressCompute {
let template_addr = spawn.template_addr();
buf.extend_from_slice(template_addr.as_slice());

let hash = DefaultHasher::hash(&buf);
let hash = Blake3Hasher::hash(&buf);
let addr = Address::from(&hash[0..Address::len()]);

addr
Expand Down
4 changes: 2 additions & 2 deletions crates/runtime/src/env/default/hasher.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use svm_hash::{DefaultHasher, Hasher};
use svm_hash::{Blake3Hasher, Hasher};
use svm_types::Template;

use super::super::traits::TemplateHasher;
Expand All @@ -10,6 +10,6 @@ pub struct DefaultTemplateHasher;
impl TemplateHasher for DefaultTemplateHasher {
#[inline]
fn hash(template: &Template) -> TemplateHash {
DefaultHasher::hash(template.code())
Blake3Hasher::hash(template.code())
}
}
25 changes: 25 additions & 0 deletions crates/state/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "svm-state"
version = "0.0.0"
authors = ["Spacemesh SVM Team"]
license = "MIT"
edition = "2018"
readme = "README.md"
repository = "https://github.com/spacemeshos/svm"
homepage = "https://github.com/spacemeshos/svm"
description = "Spacemesh Virtual Machine"
publish = false

[dependencies]
anyhow = "1"
blake3 = "1"
futures = "0.3"
sqlx = { version = "0.5", features = ["runtime-tokio-rustls", "sqlite", "macros"] }
svm-hash = { path = "../hash" }
thiserror = "1"

[dev-dependencies]
quickcheck = "1"
quickcheck_async = "0.1"
quickcheck_macros = "1"
tokio = { version = "1", features = ["rt", "macros"] }
27 changes: 27 additions & 0 deletions crates/state/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use std::fmt::Debug;

use crate::Fingerprint;

/// An alias for [`Result`](std::result::Result)'s with [`StorageError`].
pub type Result<T> = std::result::Result<T, StorageError>;

/// A sum type for all error conditions that can arise in this crate.
#[derive(Debug, thiserror::Error)]
pub enum StorageError {
/// The storage layer contains some dirty changes that must be either saved
/// or rollbacked before attempting such operation.
#[error("Please checkout dirty changes or rollback to avoid data loss.")]
DirtyChanges,

/// Two checkpoints have resulted in key collision, which prevents unordered
/// transaction replaying.
#[error("Key collision from two different checkpoints.")]
KeyCollision {
/// They Blake3 hash of the key that caused this collision.
key_hash: Fingerprint,
},

/// A SQLite error happened.
#[error("SQLite error.")]
Sqlite(#[from] sqlx::Error),
}
Loading

0 comments on commit 87f892d

Please sign in to comment.