mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
Replace old blockchain rocksdb module with new sled blockchain stores.
This commit is contained in:
70
Cargo.lock
generated
70
Cargo.lock
generated
@@ -892,7 +892,7 @@ dependencies = [
|
||||
"async-trait",
|
||||
"bdk",
|
||||
"bitcoin",
|
||||
"clap 3.1.8",
|
||||
"clap 3.1.9",
|
||||
"darkfi",
|
||||
"easy-parallel",
|
||||
"futures",
|
||||
@@ -1017,16 +1017,16 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "3.1.8"
|
||||
version = "3.1.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "71c47df61d9e16dc010b55dba1952a57d8c215dbb533fd13cdd13369aac73b1c"
|
||||
checksum = "6aad2534fad53df1cc12519c5cda696dd3e20e6118a027e24054aea14a0bdcbe"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"clap_derive",
|
||||
"clap_lex",
|
||||
"indexmap",
|
||||
"lazy_static",
|
||||
"os_str_bytes",
|
||||
"strsim 0.10.0",
|
||||
"termcolor",
|
||||
"textwrap 0.15.0",
|
||||
@@ -1045,6 +1045,15 @@ dependencies = [
|
||||
"syn 1.0.91",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "189ddd3b5d32a70b35e7686054371742a937b0d99128e76dde6340210e966669"
|
||||
dependencies = [
|
||||
"os_str_bytes",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cloudabi"
|
||||
version = "0.0.3"
|
||||
@@ -1576,7 +1585,7 @@ dependencies = [
|
||||
"async-executor",
|
||||
"async-std",
|
||||
"async-trait",
|
||||
"clap 3.1.8",
|
||||
"clap 3.1.9",
|
||||
"darkfi",
|
||||
"easy-parallel",
|
||||
"futures",
|
||||
@@ -1624,7 +1633,7 @@ dependencies = [
|
||||
"bs58",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"clap 3.1.8",
|
||||
"clap 3.1.9",
|
||||
"crypto_api_chachapoly",
|
||||
"darkfi-derive",
|
||||
"darkfi-derive-internal",
|
||||
@@ -1642,6 +1651,7 @@ dependencies = [
|
||||
"incrementalmerkletree",
|
||||
"indexmap",
|
||||
"itertools",
|
||||
"lazy-init",
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"libsqlite3-sys",
|
||||
@@ -1703,7 +1713,7 @@ dependencies = [
|
||||
"async-executor",
|
||||
"async-std",
|
||||
"async-trait",
|
||||
"clap 3.1.8",
|
||||
"clap 3.1.9",
|
||||
"darkfi",
|
||||
"easy-parallel",
|
||||
"fxhash",
|
||||
@@ -2005,7 +2015,7 @@ version = "0.3.0"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"async-std",
|
||||
"clap 3.1.8",
|
||||
"clap 3.1.9",
|
||||
"darkfi",
|
||||
"easy-parallel",
|
||||
"fxhash",
|
||||
@@ -2032,7 +2042,7 @@ name = "drk"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"clap 3.1.8",
|
||||
"clap 3.1.9",
|
||||
"darkfi",
|
||||
"log",
|
||||
"prettytable-rs",
|
||||
@@ -2323,13 +2333,16 @@ dependencies = [
|
||||
"async-executor",
|
||||
"async-std",
|
||||
"async-trait",
|
||||
"blake3",
|
||||
"chrono",
|
||||
"ctrlc-async",
|
||||
"darkfi",
|
||||
"easy-parallel",
|
||||
"futures-lite",
|
||||
"hex",
|
||||
"lazy-init",
|
||||
"log",
|
||||
"num-bigint",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
@@ -2360,9 +2373,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "filetime"
|
||||
version = "0.2.15"
|
||||
version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "975ccf83d8d9d0d84682850a38c8169027be83368805971cc4f238c2b245bc98"
|
||||
checksum = "c0408e2626025178a6a7f7ffc05a25bc47103229f19c113755de7bf63816290c"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
@@ -2647,7 +2660,7 @@ dependencies = [
|
||||
"async-channel",
|
||||
"async-executor",
|
||||
"async-std",
|
||||
"clap 3.1.8",
|
||||
"clap 3.1.9",
|
||||
"darkfi",
|
||||
"easy-parallel",
|
||||
"log",
|
||||
@@ -3055,9 +3068,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "incrementalmerkletree"
|
||||
version = "0.2.0"
|
||||
version = "0.3.0-beta.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "186fd3ab92aeac865d4b80b410de9a7b341d31ba8281373caed0b6d17b2b5e96"
|
||||
checksum = "5812f2cfa06a7694b842402e9a100529d80fdc3022ead65ad98ce0af0bcd3311"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
@@ -3134,7 +3147,7 @@ dependencies = [
|
||||
"async-executor",
|
||||
"async-std",
|
||||
"async-trait",
|
||||
"clap 3.1.8",
|
||||
"clap 3.1.9",
|
||||
"darkfi",
|
||||
"easy-parallel",
|
||||
"futures",
|
||||
@@ -3798,9 +3811,6 @@ name = "os_str_bytes"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e22443d1643a904602595ba1cd8f7d896afe56d26712531c5ff73a15b2fbf64"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ouroboros"
|
||||
@@ -6091,9 +6101,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sqlx"
|
||||
version = "0.5.12"
|
||||
version = "0.5.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2be6e4d8b60285763c7a0c17f57839d5f1e864d948fe7ff26eaf38f04db95fc"
|
||||
checksum = "551873805652ba0d912fec5bbb0f8b4cdd96baf8e2ebf5970e5671092966019b"
|
||||
dependencies = [
|
||||
"sqlx-core",
|
||||
"sqlx-macros",
|
||||
@@ -6101,9 +6111,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-core"
|
||||
version = "0.5.12"
|
||||
version = "0.5.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5728d5a4de38574e1a43139cf1d0124e978af8c19ea795d1d61c287785924cf2"
|
||||
checksum = "e48c61941ccf5ddcada342cd59e3e5173b007c509e1e8e990dafc830294d9dc5"
|
||||
dependencies = [
|
||||
"ahash 0.7.6",
|
||||
"atoi",
|
||||
@@ -6142,9 +6152,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-macros"
|
||||
version = "0.5.12"
|
||||
version = "0.5.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cfce1fd7df05de96f76eb0d452e5ce8b106607933ac3c9a8f5c65c1ecc5955f5"
|
||||
checksum = "bc0fba2b0cae21fc00fe6046f8baa4c7fcb49e379f0f592b04696607f69ed2e1"
|
||||
dependencies = [
|
||||
"dotenv",
|
||||
"either",
|
||||
@@ -6161,9 +6171,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "sqlx-rt"
|
||||
version = "0.5.12"
|
||||
version = "0.5.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f2cc78368bdd33ba6ad1c300f2b9ff4a844f9d7db140c34bc61ef304e1fc160"
|
||||
checksum = "4db708cd3e459078f85f39f96a00960bd841f66ee2a669e90bf36907f5a79aae"
|
||||
dependencies = [
|
||||
"async-native-tls 0.3.3",
|
||||
"async-std",
|
||||
@@ -6350,7 +6360,7 @@ dependencies = [
|
||||
"async-std",
|
||||
"async-trait",
|
||||
"chrono",
|
||||
"clap 3.1.8",
|
||||
"clap 3.1.9",
|
||||
"darkfi",
|
||||
"easy-parallel",
|
||||
"futures",
|
||||
@@ -6373,7 +6383,7 @@ dependencies = [
|
||||
"async-std",
|
||||
"async-trait",
|
||||
"chrono",
|
||||
"clap 3.1.8",
|
||||
"clap 3.1.9",
|
||||
"ctrlc-async",
|
||||
"darkfi",
|
||||
"easy-parallel",
|
||||
@@ -6877,7 +6887,7 @@ name = "vanityaddr"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"bs58",
|
||||
"clap 3.1.8",
|
||||
"clap 3.1.9",
|
||||
"ctrlc",
|
||||
"darkfi",
|
||||
"indicatif 0.17.0-rc.10",
|
||||
@@ -7541,7 +7551,7 @@ dependencies = [
|
||||
name = "zkas"
|
||||
version = "0.3.0"
|
||||
dependencies = [
|
||||
"clap 3.1.8",
|
||||
"clap 3.1.9",
|
||||
"darkfi",
|
||||
]
|
||||
|
||||
|
||||
23
Cargo.toml
23
Cargo.toml
@@ -75,6 +75,7 @@ url = {version = "2.2.2", features = ["serde"], optional = true}
|
||||
dirs = {version = "4.0.0", optional = true}
|
||||
subtle = {version = "2.4.1", optional = true}
|
||||
lazy_static = {version = "1.4.0", optional = true}
|
||||
lazy-init = {version = "0.5.0", optional = true}
|
||||
fxhash = {version = "0.2.1", optional = true}
|
||||
indexmap = {version = "1.8.1", optional = true}
|
||||
itertools = {version = "0.10.3", optional = true}
|
||||
@@ -104,7 +105,7 @@ arrayvec = {version = "0.7.2", optional = true}
|
||||
blake2b_simd = {version = "1.0.0", optional = true}
|
||||
pasta_curves = {version = "0.3.0", optional = true}
|
||||
crypto_api_chachapoly = {version = "0.5.0", optional = true}
|
||||
incrementalmerkletree = {version = "0.2.0", optional = true}
|
||||
incrementalmerkletree = {version = "0.3.0-beta.2", optional = true}
|
||||
halo2_proofs = {version = "0.1.0-beta.4", features = ["dev-graph", "gadget-traces", "sanity-checks"], optional = true}
|
||||
halo2_gadgets = {version = "0.1.0-beta.3", features = ["dev-graph", "test-dependencies"], optional = true}
|
||||
|
||||
@@ -193,25 +194,13 @@ rpc = [
|
||||
]
|
||||
|
||||
blockchain = [
|
||||
"rocksdb",
|
||||
"sled",
|
||||
"chrono",
|
||||
"rand",
|
||||
|
||||
"async-runtime",
|
||||
"util",
|
||||
"crypto",
|
||||
"net",
|
||||
"blockchain2",
|
||||
]
|
||||
|
||||
blockchain2 = [
|
||||
"blake3",
|
||||
"chrono",
|
||||
"indexmap",
|
||||
"sled",
|
||||
|
||||
"crypto",
|
||||
"tx",
|
||||
"net",
|
||||
"util",
|
||||
]
|
||||
@@ -293,6 +282,7 @@ node = [
|
||||
"zeromq",
|
||||
"signal-hook",
|
||||
"signal-hook-async-std",
|
||||
"lazy-init",
|
||||
|
||||
"async-runtime",
|
||||
"blockchain",
|
||||
@@ -319,6 +309,11 @@ raft = [
|
||||
"rpc",
|
||||
]
|
||||
|
||||
tx = [
|
||||
"crypto",
|
||||
"util",
|
||||
]
|
||||
|
||||
[[example]]
|
||||
name = "net"
|
||||
path = "example/net.rs"
|
||||
|
||||
@@ -16,7 +16,7 @@ async-trait = "0.1.53"
|
||||
blake3 = "1.3.1"
|
||||
chrono = "0.4.19"
|
||||
ctrlc-async = {version = "3.2.2", default-features = false, features = ["async-std", "termination"]}
|
||||
darkfi = {path = "../../", features = ["blockchain2", "wallet", "rpc", "net", "node"]}
|
||||
darkfi = {path = "../../", features = ["blockchain", "wallet", "rpc", "net", "node"]}
|
||||
easy-parallel = "3.2.0"
|
||||
futures-lite = "1.12.0"
|
||||
hex = "0.4.3"
|
||||
|
||||
@@ -19,7 +19,7 @@ use url::Url;
|
||||
|
||||
use darkfi::{
|
||||
async_daemonize,
|
||||
blockchain2::{NullifierStore, RootStore},
|
||||
blockchain::{NullifierStore, RootStore},
|
||||
cli_desc,
|
||||
consensus2::{
|
||||
Timestamp, ValidatorState, MAINNET_GENESIS_HASH_BYTES, TESTNET_GENESIS_HASH_BYTES,
|
||||
|
||||
@@ -1,7 +1,98 @@
|
||||
pub mod rocks;
|
||||
pub mod slab;
|
||||
pub mod slabstore;
|
||||
use std::io;
|
||||
|
||||
pub use rocks::{Rocks, RocksColumn};
|
||||
pub use slab::Slab;
|
||||
pub use slabstore::SlabStore;
|
||||
use crate::{
|
||||
consensus2::{block::BlockProposal, util::Timestamp, Block},
|
||||
impl_vec,
|
||||
util::serial::{Decodable, Encodable, ReadExt, VarInt, WriteExt},
|
||||
Result,
|
||||
};
|
||||
|
||||
pub mod blockstore;
|
||||
pub use blockstore::{BlockOrderStore, BlockStore};
|
||||
|
||||
pub mod metadatastore;
|
||||
pub use metadatastore::StreamletMetadataStore;
|
||||
|
||||
pub mod nfstore;
|
||||
pub use nfstore::NullifierStore;
|
||||
|
||||
pub mod rootstore;
|
||||
pub use rootstore::RootStore;
|
||||
|
||||
pub mod txstore;
|
||||
pub use txstore::TxStore;
|
||||
|
||||
pub struct Blockchain {
|
||||
/// Blocks sled tree
|
||||
pub blocks: BlockStore,
|
||||
/// Block order sled tree
|
||||
pub order: BlockOrderStore,
|
||||
/// Transactions sled tree
|
||||
pub transactions: TxStore,
|
||||
/// Streamlet metadata sled tree
|
||||
pub streamlet_metadata: StreamletMetadataStore,
|
||||
/// Nullifiers sled tree
|
||||
pub nullifiers: NullifierStore,
|
||||
/// Merkle roots sled tree
|
||||
pub merkle_roots: RootStore,
|
||||
}
|
||||
|
||||
impl Blockchain {
|
||||
pub fn new(db: &sled::Db, genesis_ts: Timestamp, genesis_data: blake3::Hash) -> Result<Self> {
|
||||
let blocks = BlockStore::new(db, genesis_ts, genesis_data)?;
|
||||
let order = BlockOrderStore::new(db, genesis_ts, genesis_data)?;
|
||||
let transactions = TxStore::new(db)?;
|
||||
let streamlet_metadata = StreamletMetadataStore::new(db)?;
|
||||
let nullifiers = NullifierStore::new(db)?;
|
||||
let merkle_roots = RootStore::new(db)?;
|
||||
|
||||
Ok(Self { blocks, order, transactions, streamlet_metadata, nullifiers, merkle_roots })
|
||||
}
|
||||
|
||||
/// Batch insert [`BlockProposal`]s.
|
||||
pub fn add(&mut self, proposals: &[BlockProposal]) -> Result<Vec<blake3::Hash>> {
|
||||
// TODO: Engineer this function in a better way.
|
||||
let mut ret = Vec::with_capacity(proposals.len());
|
||||
|
||||
for prop in proposals {
|
||||
// Store transactions
|
||||
let tx_hashes = self.transactions.insert(&prop.txs)?;
|
||||
|
||||
// Store block
|
||||
let block =
|
||||
Block { st: prop.st, sl: prop.sl, txs: tx_hashes, metadata: prop.metadata.clone() };
|
||||
let blockhash = self.blocks.insert(&[block.clone()])?;
|
||||
ret.push(blockhash[0]);
|
||||
|
||||
// Store block order
|
||||
self.order.insert(&[block.sl], &[blockhash[0]])?;
|
||||
|
||||
// Store streamlet metadata
|
||||
self.streamlet_metadata.insert(&[blockhash[0]], &[prop.sm.clone()])?;
|
||||
}
|
||||
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
/// Retrieve the last block slot and hash
|
||||
pub fn last(&self) -> Result<Option<(u64, blake3::Hash)>> {
|
||||
self.order.get_last()
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for blake3::Hash {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
s.write_slice(self.as_bytes())?;
|
||||
Ok(32)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for blake3::Hash {
|
||||
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
||||
let mut bytes = [0u8; 32];
|
||||
d.read_slice(&mut bytes)?;
|
||||
Ok(bytes.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl_vec!(blake3::Hash);
|
||||
|
||||
@@ -1,158 +0,0 @@
|
||||
use std::{marker::PhantomData, path::Path};
|
||||
|
||||
use async_std::sync::Arc;
|
||||
use rocksdb::{ColumnFamily, ColumnFamilyDescriptor, Options, DB};
|
||||
|
||||
use crate::{
|
||||
util::serial::{deserialize, serialize, Decodable, Encodable},
|
||||
Error, Result,
|
||||
};
|
||||
|
||||
pub enum IteratorMode {
|
||||
Start,
|
||||
End,
|
||||
}
|
||||
|
||||
pub trait Column {
|
||||
const NAME: &'static str;
|
||||
}
|
||||
|
||||
pub mod columns {
|
||||
pub struct Slabs;
|
||||
pub struct Nullifiers;
|
||||
pub struct MerkleRoots;
|
||||
}
|
||||
|
||||
impl Column for columns::Slabs {
|
||||
const NAME: &'static str = "slabs";
|
||||
}
|
||||
|
||||
impl Column for columns::Nullifiers {
|
||||
const NAME: &'static str = "nullifiers";
|
||||
}
|
||||
|
||||
impl Column for columns::MerkleRoots {
|
||||
const NAME: &'static str = "merkleroots";
|
||||
}
|
||||
|
||||
pub struct Rocks {
|
||||
db: DB,
|
||||
}
|
||||
|
||||
impl Rocks {
|
||||
pub fn new(path: &Path) -> Result<Arc<Self>> {
|
||||
// column family options
|
||||
let cf_opts = Options::default();
|
||||
|
||||
// default column family
|
||||
let default_cf =
|
||||
ColumnFamilyDescriptor::new(rocksdb::DEFAULT_COLUMN_FAMILY_NAME, cf_opts.clone());
|
||||
// slabs column family
|
||||
let slab_cf = ColumnFamilyDescriptor::new(columns::Slabs::NAME, cf_opts.clone());
|
||||
// nullifiers column family
|
||||
let nullifiers_cf = ColumnFamilyDescriptor::new(columns::Nullifiers::NAME, cf_opts.clone());
|
||||
// merkleroots column family
|
||||
let merkleroots_cf = ColumnFamilyDescriptor::new(columns::MerkleRoots::NAME, cf_opts);
|
||||
|
||||
// column families
|
||||
let cfs = vec![default_cf, slab_cf, nullifiers_cf, merkleroots_cf];
|
||||
|
||||
// database options
|
||||
let mut opt = Options::default();
|
||||
opt.create_if_missing(true);
|
||||
opt.create_missing_column_families(true);
|
||||
|
||||
// open database with following options and cf
|
||||
let db = DB::open_cf_descriptors(&opt, path, cfs)?;
|
||||
|
||||
Ok(Arc::new(Self { db }))
|
||||
}
|
||||
|
||||
pub fn cf_handle<C>(&self) -> Result<&ColumnFamily>
|
||||
where
|
||||
C: Column,
|
||||
{
|
||||
self.db.cf_handle(C::NAME).ok_or_else(|| Error::RocksdbError("unknown column".to_string()))
|
||||
}
|
||||
|
||||
pub fn put_cf(&self, cf: &ColumnFamily, key: Vec<u8>, value: Vec<u8>) -> Result<()> {
|
||||
self.db.put_cf(cf, key, value)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_cf(&self, cf: &ColumnFamily, key: Vec<u8>) -> Result<Option<Vec<u8>>> {
|
||||
let val = self.db.get_cf(cf, key)?;
|
||||
Ok(val)
|
||||
}
|
||||
|
||||
pub fn key_exist_cf(&self, cf: &ColumnFamily, key: Vec<u8>) -> Result<bool> {
|
||||
let val = self.db.get_cf(cf, key)?;
|
||||
Ok(val.is_some())
|
||||
}
|
||||
|
||||
pub fn iterator(&self, cf: &ColumnFamily, iterator_mode: IteratorMode) -> rocksdb::DBIterator {
|
||||
let iterator_mode = match iterator_mode {
|
||||
IteratorMode::Start => rocksdb::IteratorMode::Start,
|
||||
IteratorMode::End => rocksdb::IteratorMode::End,
|
||||
};
|
||||
self.db.iterator_cf(cf, iterator_mode)
|
||||
}
|
||||
|
||||
pub fn destroy(path: &Path) -> Result<()> {
|
||||
DB::destroy(&Options::default(), path)?;
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RocksColumn<T: Column> {
|
||||
rocks: Arc<Rocks>,
|
||||
column: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: Column> RocksColumn<T> {
|
||||
pub fn new(rocks: Arc<Rocks>) -> RocksColumn<T> {
|
||||
RocksColumn { rocks, column: PhantomData }
|
||||
}
|
||||
fn cf_handle(&self) -> Result<&ColumnFamily> {
|
||||
self.rocks.cf_handle::<T>()
|
||||
}
|
||||
|
||||
pub fn put(&self, key: impl Encodable, value: impl Encodable) -> Result<()> {
|
||||
let key = serialize(&key);
|
||||
let value = serialize(&value);
|
||||
let cf = self.cf_handle()?;
|
||||
self.rocks.put_cf(cf, key, value)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get(&self, key: impl Encodable) -> Result<Option<Vec<u8>>> {
|
||||
let key = serialize(&key);
|
||||
let cf = self.cf_handle()?;
|
||||
let val = self.rocks.get_cf(cf, key)?;
|
||||
Ok(val)
|
||||
}
|
||||
|
||||
pub fn get_value_deserialized<D: Decodable>(&self, key: Vec<u8>) -> Result<Option<D>> {
|
||||
let value = self.get(key)?;
|
||||
match value {
|
||||
Some(v) => {
|
||||
let v: D = deserialize(&v)?;
|
||||
Ok(Some(v))
|
||||
}
|
||||
None => Ok(None),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn key_exist(&self, key: impl Encodable) -> Result<bool> {
|
||||
let key = serialize(&key);
|
||||
let cf = self.cf_handle()?;
|
||||
let val = self.rocks.key_exist_cf(cf, key)?;
|
||||
Ok(val)
|
||||
}
|
||||
|
||||
pub fn iterator(&self, iterator_mode: IteratorMode) -> Result<rocksdb::DBIterator> {
|
||||
let cf = self.cf_handle()?;
|
||||
let iter = self.rocks.iterator(cf, iterator_mode);
|
||||
Ok(iter)
|
||||
}
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
use crate::{
|
||||
util::serial::{Decodable, Encodable},
|
||||
Result,
|
||||
};
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct Slab {
|
||||
index: u64,
|
||||
payload: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Slab {
|
||||
pub fn new(payload: Vec<u8>) -> Self {
|
||||
let index = 0;
|
||||
Slab { index, payload }
|
||||
}
|
||||
|
||||
pub fn set_index(&mut self, index: u64) {
|
||||
self.index = index;
|
||||
}
|
||||
|
||||
pub fn get_index(&self) -> u64 {
|
||||
self.index
|
||||
}
|
||||
|
||||
pub fn get_payload(&self) -> Vec<u8> {
|
||||
self.payload.clone()
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for Slab {
|
||||
fn encode<S: std::io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
let mut len = 0;
|
||||
len += self.index.encode(&mut s)?;
|
||||
len += self.payload.encode(&mut s)?;
|
||||
Ok(len)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for Slab {
|
||||
fn decode<D: std::io::Read>(mut d: D) -> Result<Self> {
|
||||
Ok(Self { index: Decodable::decode(&mut d)?, payload: Decodable::decode(&mut d)? })
|
||||
}
|
||||
}
|
||||
@@ -1,64 +0,0 @@
|
||||
use std::sync::Arc;
|
||||
|
||||
use log::debug;
|
||||
|
||||
use super::{
|
||||
rocks::{columns, IteratorMode, RocksColumn},
|
||||
slab::Slab,
|
||||
};
|
||||
use crate::{
|
||||
util::serial::{deserialize, serialize},
|
||||
Result,
|
||||
};
|
||||
|
||||
pub struct SlabStore {
|
||||
rocks: RocksColumn<columns::Slabs>,
|
||||
}
|
||||
|
||||
impl SlabStore {
|
||||
pub fn new(rocks: RocksColumn<columns::Slabs>) -> Result<Arc<Self>> {
|
||||
Ok(Arc::new(SlabStore { rocks }))
|
||||
}
|
||||
|
||||
pub fn get(&self, key: Vec<u8>) -> Result<Option<Vec<u8>>> {
|
||||
debug!(target: "SLABSTORE", "get value");
|
||||
let key: u64 = deserialize(&key)?;
|
||||
let value = self.rocks.get(key)?;
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn put(&self, slab: Slab) -> Result<Option<u64>> {
|
||||
debug!(target: "SLABSTORE", "Put slab");
|
||||
let last_index = self.get_last_index()?;
|
||||
let key = last_index + 1;
|
||||
|
||||
if slab.get_index() == key {
|
||||
self.rocks.put(key, slab)?;
|
||||
Ok(Some(key))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_value_deserialized(&self, key: Vec<u8>) -> Result<Option<Slab>> {
|
||||
self.rocks.get_value_deserialized::<Slab>(key)
|
||||
}
|
||||
|
||||
pub fn get_last_index(&self) -> Result<u64> {
|
||||
debug!(target: "SLABSTORE", "Get last index");
|
||||
let last_index = self.rocks.iterator(IteratorMode::End)?.next();
|
||||
match last_index {
|
||||
Some((index, _)) => Ok(deserialize(&index)?),
|
||||
None => Ok(0),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_last_index_as_bytes(&self) -> Result<Vec<u8>> {
|
||||
debug!(target: "SLABSTORE", "Get last index as bytes");
|
||||
let last_index = self.rocks.iterator(IteratorMode::End)?.next();
|
||||
match last_index {
|
||||
Some((index, _)) => Ok(index.to_vec()),
|
||||
None => Ok(serialize::<u64>(&0)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,98 +0,0 @@
|
||||
use std::io;
|
||||
|
||||
use crate::{
|
||||
consensus2::{block::BlockProposal, util::Timestamp, Block},
|
||||
impl_vec,
|
||||
util::serial::{Decodable, Encodable, ReadExt, VarInt, WriteExt},
|
||||
Result,
|
||||
};
|
||||
|
||||
pub mod blockstore;
|
||||
pub use blockstore::{BlockOrderStore, BlockStore};
|
||||
|
||||
pub mod metadatastore;
|
||||
pub use metadatastore::StreamletMetadataStore;
|
||||
|
||||
pub mod nfstore;
|
||||
pub use nfstore::NullifierStore;
|
||||
|
||||
pub mod rootstore;
|
||||
pub use rootstore::RootStore;
|
||||
|
||||
pub mod txstore;
|
||||
pub use txstore::TxStore;
|
||||
|
||||
pub struct Blockchain {
|
||||
/// Blocks sled tree
|
||||
pub blocks: BlockStore,
|
||||
/// Block order sled tree
|
||||
pub order: BlockOrderStore,
|
||||
/// Transactions sled tree
|
||||
pub transactions: TxStore,
|
||||
/// Streamlet metadata sled tree
|
||||
pub streamlet_metadata: StreamletMetadataStore,
|
||||
/// Nullifiers sled tree
|
||||
pub nullifiers: NullifierStore,
|
||||
/// Merkle roots sled tree
|
||||
pub merkle_roots: RootStore,
|
||||
}
|
||||
|
||||
impl Blockchain {
|
||||
pub fn new(db: &sled::Db, genesis_ts: Timestamp, genesis_data: blake3::Hash) -> Result<Self> {
|
||||
let blocks = BlockStore::new(db, genesis_ts, genesis_data)?;
|
||||
let order = BlockOrderStore::new(db, genesis_ts, genesis_data)?;
|
||||
let transactions = TxStore::new(db)?;
|
||||
let streamlet_metadata = StreamletMetadataStore::new(db)?;
|
||||
let nullifiers = NullifierStore::new(db)?;
|
||||
let merkle_roots = RootStore::new(db)?;
|
||||
|
||||
Ok(Self { blocks, order, transactions, streamlet_metadata, nullifiers, merkle_roots })
|
||||
}
|
||||
|
||||
/// Batch insert [`BlockProposal`]s.
|
||||
pub fn add(&mut self, proposals: &[BlockProposal]) -> Result<Vec<blake3::Hash>> {
|
||||
// TODO: Engineer this function in a better way.
|
||||
let mut ret = Vec::with_capacity(proposals.len());
|
||||
|
||||
for prop in proposals {
|
||||
// Store transactions
|
||||
let tx_hashes = self.transactions.insert(&prop.txs)?;
|
||||
|
||||
// Store block
|
||||
let block =
|
||||
Block { st: prop.st, sl: prop.sl, txs: tx_hashes, metadata: prop.metadata.clone() };
|
||||
let blockhash = self.blocks.insert(&[block.clone()])?;
|
||||
ret.push(blockhash[0]);
|
||||
|
||||
// Store block order
|
||||
self.order.insert(&[block.sl], &[blockhash[0]])?;
|
||||
|
||||
// Store streamlet metadata
|
||||
self.streamlet_metadata.insert(&[blockhash[0]], &[prop.sm.clone()])?;
|
||||
}
|
||||
|
||||
Ok(ret)
|
||||
}
|
||||
|
||||
/// Retrieve the last block slot and hash
|
||||
pub fn last(&self) -> Result<Option<(u64, blake3::Hash)>> {
|
||||
self.order.get_last()
|
||||
}
|
||||
}
|
||||
|
||||
impl Encodable for blake3::Hash {
|
||||
fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
|
||||
s.write_slice(self.as_bytes())?;
|
||||
Ok(32)
|
||||
}
|
||||
}
|
||||
|
||||
impl Decodable for blake3::Hash {
|
||||
fn decode<D: io::Read>(mut d: D) -> Result<Self> {
|
||||
let mut bytes = [0u8; 32];
|
||||
d.read_slice(&mut bytes)?;
|
||||
Ok(bytes.into())
|
||||
}
|
||||
}
|
||||
|
||||
impl_vec!(blake3::Hash);
|
||||
@@ -14,7 +14,7 @@ use super::{
|
||||
Vote,
|
||||
};
|
||||
use crate::{
|
||||
blockchain2::Blockchain,
|
||||
blockchain::Blockchain,
|
||||
crypto::{
|
||||
keypair::{PublicKey, SecretKey},
|
||||
schnorr::{SchnorrPublic, SchnorrSecret},
|
||||
@@ -84,7 +84,7 @@ impl ValidatorState {
|
||||
// TODO: Clock sync
|
||||
// TODO: ID shouldn't be done like this
|
||||
pub fn new(
|
||||
db: &sled::Db, // <-- TODO: Avoid this with some wrapping, sled should only be in blockchain2
|
||||
db: &sled::Db, // <-- TODO: Avoid this with some wrapping, sled should only be in blockchain
|
||||
id: u64,
|
||||
genesis_ts: Timestamp,
|
||||
genesis_data: blake3::Hash,
|
||||
|
||||
@@ -5,12 +5,9 @@ pub use error::{ClientFailed, ClientResult, Error, Result, VerifyFailed, VerifyR
|
||||
pub mod blockchain;
|
||||
|
||||
#[cfg(feature = "blockchain2")]
|
||||
pub mod blockchain2;
|
||||
|
||||
#[cfg(feature = "blockchain")]
|
||||
pub mod consensus;
|
||||
|
||||
#[cfg(feature = "blockchain2")]
|
||||
#[cfg(feature = "blockchain")]
|
||||
pub mod consensus2;
|
||||
|
||||
#[cfg(feature = "crypto")]
|
||||
|
||||
@@ -3,7 +3,7 @@ use lazy_init::Lazy;
|
||||
use log::{debug, error};
|
||||
|
||||
use crate::{
|
||||
blockchain2::{nfstore::NullifierStore, rootstore::RootStore},
|
||||
blockchain::{nfstore::NullifierStore, rootstore::RootStore},
|
||||
crypto::{
|
||||
coin::Coin,
|
||||
keypair::{PublicKey, SecretKey},
|
||||
|
||||
Reference in New Issue
Block a user