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

Global State: versioned KV store with root signature calculation #333

Merged
merged 57 commits into from
Aug 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
4bd8ef6
WIP
neysofu Jul 27, 2021
2338a6a
Wip
neysofu Jul 27, 2021
462f589
Wip
neysofu Jul 27, 2021
6252878
Get the trie-db impl to compile
neysofu Jul 28, 2021
c0b59eb
Wip
neysofu Jul 29, 2021
1989b6f
Key value basics are ready
neysofu Jul 30, 2021
e212917
Improve documentation
neysofu Jul 30, 2021
9cb64ef
Change API to reflect support for dirty changes
neysofu Jul 30, 2021
9aec819
Fix key retrieval bugs
neysofu Aug 3, 2021
a98d172
Simplify root signature logic with XOR
neysofu Aug 3, 2021
45aab0f
Fix checkout XORing root signature
neysofu Aug 3, 2021
bc69bec
Fix commit id bug
neysofu Aug 3, 2021
c5f360a
Remove trie node implementation
neysofu Aug 4, 2021
007903f
Move Result into error.rs
neysofu Aug 4, 2021
33205ce
Improve doc comments
neysofu Aug 4, 2021
ba6365d
Switch to using Blake everywhere
neysofu Aug 13, 2021
41a1d1f
Merge branch 'master' into global-state
neysofu Aug 13, 2021
556bcc4
Fix Cargo.toml duplicates
neysofu Aug 13, 2021
9f63717
Remove unused deps in Cargo.toml
neysofu Aug 13, 2021
b5bde7e
Empty lines in enum
neysofu Aug 13, 2021
867b1f8
Add SQL length check to key_hash
neysofu Aug 13, 2021
0f52299
Add some lints to svm-state
neysofu Aug 13, 2021
5d4a605
Rename signature to fingerprint
neysofu Aug 13, 2021
b9e9cc8
Add [env] section to Cargo.toml
neysofu Aug 13, 2021
3333799
Replace DATABASE_URL even if set
neysofu Aug 13, 2021
e77fe9c
Restore old Cargo.lock
neysofu Aug 13, 2021
1abe9c3
Fix build time issues due to DATABASE_URL
neysofu Aug 16, 2021
0418356
Don't delete existing data in SQLite instance
neysofu Aug 16, 2021
a39b511
Use SQLx functions, not macros
neysofu Aug 16, 2021
0c8de0f
Finish renaming to Fingerprint
neysofu Aug 16, 2021
ad453a4
Simplify in-memory creation logic
neysofu Aug 16, 2021
b34e26c
Delete unneeded SQLite instance in repo
neysofu Aug 16, 2021
59b71dc
Improve first commit logic
neysofu Aug 16, 2021
ab73d11
Rename some commit-related functions
neysofu Aug 16, 2021
a6003ae
Only touch DBs on commits, not checkpoints
neysofu Aug 17, 2021
23139e1
Fix indentation of queries and checkpoint in test
neysofu Aug 17, 2021
b87ac63
Add support for easing history
neysofu Aug 17, 2021
d1a7e0f
Rename some commit ops to layer
neysofu Aug 17, 2021
f47ae8b
Improve testing cov
neysofu Aug 17, 2021
5e0c679
Remove old error types
neysofu Aug 18, 2021
baf3524
Improve tests
neysofu Aug 18, 2021
db66ccd
Fix rewind-related query and test
neysofu Aug 18, 2021
dedfa71
More tests
neysofu Aug 18, 2021
a11a013
Fix collision-related tests
neysofu Aug 18, 2021
adfc7bc
deny(missing_docs)
neysofu Aug 18, 2021
9bed274
Merge branch 'master' into global-state
neysofu Aug 18, 2021
50c51b9
Remove gs -> storage; remove funty dep
neysofu Aug 19, 2021
3e6f807
Mark layers by "readyness" and initial empty layer
neysofu Aug 19, 2021
d096c14
Fix historical testing
neysofu Aug 19, 2021
9e250ac
Ambiguous ID column name
neysofu Aug 19, 2021
8a90bae
Add layer ID asserts in getters
neysofu Aug 19, 2021
6ef98ca
Cleanup bad layers in GS upon initialization
neysofu Aug 19, 2021
5b4ec01
Explicit `ready = 1` query in current getter
neysofu Aug 19, 2021
4ab4770
Better join query
neysofu Aug 19, 2021
31c5b12
Change column names in queries and pass tests
neysofu Aug 19, 2021
b1a36ae
Merge branch 'master' into global-state
neysofu Aug 19, 2021
9668808
Improve top level docs
neysofu Aug 19, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
neysofu marked this conversation as resolved.
Show resolved Hide resolved

[dependencies]
anyhow = "1"
blake3 = "1"
futures = "0.3"
neysofu marked this conversation as resolved.
Show resolved Hide resolved
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