A complete blockchain implementation featuring: - synord: Full node with GHOSTDAG consensus - explorer-web: Modern React blockchain explorer with 3D DAG visualization - CLI wallet and tools - Smart contract SDK and example contracts (DEX, NFT, token) - WASM crypto library for browser/mobile
109 lines
3.3 KiB
Rust
109 lines
3.3 KiB
Rust
//! RocksDB storage layer for Synor blockchain.
|
|
//!
|
|
//! This crate provides persistent storage for:
|
|
//! - Blocks and block headers
|
|
//! - Transactions
|
|
//! - UTXO set
|
|
//! - DAG relations and GHOSTDAG data
|
|
//! - State snapshots
|
|
//! - Smart contract bytecode and state
|
|
//!
|
|
//! # Column Families
|
|
//!
|
|
//! The database is organized into column families:
|
|
//! - `headers`: Block headers indexed by hash
|
|
//! - `blocks`: Full block bodies indexed by hash
|
|
//! - `transactions`: Transactions indexed by txid
|
|
//! - `utxos`: UTXO entries indexed by outpoint
|
|
//! - `relations`: DAG parent-child relations
|
|
//! - `ghostdag`: GHOSTDAG data (blue scores, merge sets)
|
|
//! - `reachability`: Reachability intervals
|
|
//! - `metadata`: Chain metadata (tips, pruning point, etc.)
|
|
//! - `contracts`: Contract bytecode indexed by contract ID
|
|
//! - `contract_state`: Contract storage (key-value pairs per contract)
|
|
|
|
#![allow(dead_code)]
|
|
|
|
pub mod cache;
|
|
pub mod db;
|
|
pub mod stores;
|
|
|
|
pub use cache::{CacheConfig, CacheSizeInfo, CacheStats, StorageCache};
|
|
pub use db::{Database, DatabaseConfig, DbError};
|
|
pub use stores::{
|
|
BatchStore, BlockBody, BlockStore, ChainState, ContractStateStore, ContractStore,
|
|
GhostdagStore, HeaderStore, MetadataStore, RelationsStore, StoredContract,
|
|
StoredGhostdagData, StoredRelations, StoredUtxo, TransactionStore, UtxoStore,
|
|
};
|
|
|
|
/// Column family names.
|
|
pub mod cf {
|
|
pub const HEADERS: &str = "headers";
|
|
pub const BLOCKS: &str = "blocks";
|
|
pub const TRANSACTIONS: &str = "transactions";
|
|
pub const UTXOS: &str = "utxos";
|
|
pub const RELATIONS: &str = "relations";
|
|
pub const GHOSTDAG: &str = "ghostdag";
|
|
pub const REACHABILITY: &str = "reachability";
|
|
pub const METADATA: &str = "metadata";
|
|
/// Contract bytecode storage.
|
|
pub const CONTRACTS: &str = "contracts";
|
|
/// Contract state storage (key-value per contract).
|
|
pub const CONTRACT_STATE: &str = "contract_state";
|
|
|
|
/// All column family names.
|
|
pub fn all() -> Vec<&'static str> {
|
|
vec![
|
|
HEADERS,
|
|
BLOCKS,
|
|
TRANSACTIONS,
|
|
UTXOS,
|
|
RELATIONS,
|
|
GHOSTDAG,
|
|
REACHABILITY,
|
|
METADATA,
|
|
CONTRACTS,
|
|
CONTRACT_STATE,
|
|
]
|
|
}
|
|
}
|
|
|
|
/// Key prefixes for different data types within column families.
|
|
pub mod keys {
|
|
/// Prefix for block height -> hash index.
|
|
pub const HEIGHT_TO_HASH: u8 = 0x01;
|
|
/// Prefix for tip blocks.
|
|
pub const TIPS: u8 = 0x02;
|
|
/// Prefix for pruning point.
|
|
pub const PRUNING_POINT: u8 = 0x03;
|
|
/// Prefix for chain state.
|
|
pub const CHAIN_STATE: u8 = 0x04;
|
|
|
|
/// Creates a prefixed key.
|
|
pub fn prefixed_key(prefix: u8, data: &[u8]) -> Vec<u8> {
|
|
let mut key = Vec::with_capacity(1 + data.len());
|
|
key.push(prefix);
|
|
key.extend_from_slice(data);
|
|
key
|
|
}
|
|
|
|
/// Encodes a u64 as big-endian bytes for lexicographic ordering.
|
|
pub fn encode_u64(value: u64) -> [u8; 8] {
|
|
value.to_be_bytes()
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn test_column_families() {
|
|
let cfs = cf::all();
|
|
assert_eq!(cfs.len(), 10);
|
|
assert!(cfs.contains(&cf::HEADERS));
|
|
assert!(cfs.contains(&cf::UTXOS));
|
|
assert!(cfs.contains(&cf::CONTRACTS));
|
|
assert!(cfs.contains(&cf::CONTRACT_STATE));
|
|
}
|
|
}
|