Skip to content

hyra-network/Scribe-Ledger

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
οΏ½οΏ½
 
 
 
 
 
 

Repository files navigation

πŸ”₯ Hyra Scribe Ledger

Verifiable, Durable Off-Chain Storage for the AI Ecosystem

Build Status Rust License S3

πŸš€ Production-Ready | ⚑ High-Performance | πŸ”’ Cryptographically Verified | ☁️ Cloud-Native

Quick Start β€’ Features β€’ Architecture β€’ Documentation


🎯 What is Hyra Scribe Ledger?

Hyra Scribe Ledger is a distributed, immutable, append-only storage system built with Rust for the modern AI and blockchain ecosystem. It combines the speed of local storage with the durability of cloud object storage (S3), providing a multi-tier architecture optimized for both hot and cold data.

✨ Key Highlights

πŸ—οΈ Multi-Tier Architecture

  • Hot Tier: Sled embedded database
  • Cold Tier: S3-compatible object storage
  • Automatic tiering & archival
  • Seamless read-through caching

πŸ”„ Distributed Consensus

  • OpenRaft for strong consistency
  • Automatic leader election
  • Dynamic cluster membership
  • Fault-tolerant replication

⚑ High Performance

  • 200k+ writes/sec (batched)
  • 1.8M+ reads/sec (cached)
  • LRU hot data cache
  • Async I/O with Tokio

πŸ” Cryptographically Verified

  • Merkle tree proofs
  • SHA-256 hashing
  • Tamper-proof integrity
  • Audit trail support

πŸš€ Quick Start

Prerequisites

  • Rust 1.70+ - Install from rustup.rs
  • Docker (Optional) - For S3-compatible storage with MinIO

Installation & First Run

# Clone the repository
git clone https://github.com/hyra-network/Scribe-Ledger.git
cd Scribe-Ledger

# Build (release mode for best performance)
cargo build --release

# Start a single node
./target/release/scribe-node

# In another terminal, test the API
curl -X PUT http://localhost:8001/hello -d "Hello, Hyra!"
curl http://localhost:8001/hello
# Output: Hello, Hyra!

πŸŽ‰ You're up and running! The node is now serving at http://localhost:8001


🌟 Features

βœ… Production-Ready

βœ… HTTP RESTful API Simple PUT/GET/DELETE operations
βœ… S3 Integration AWS S3, MinIO, or any S3-compatible storage
βœ… Multi-Node Cluster 3+ nodes with automatic failover
βœ… Auto Discovery Nodes discover each other automatically
βœ… Prometheus Metrics Production-grade monitoring
βœ… Structured Logging Advanced logging with tracing
βœ… Docker Support Container-ready deployment
βœ… Systemd Integration Production deployment scripts

πŸ—οΈ Architecture

Multi-Tier Storage Design

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        CLIENT REQUESTS                       β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚     HTTP API Server    β”‚
              β”‚    (Axum Framework)    β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                           β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚                β”‚                β”‚
  β”Œβ”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”
  β”‚   Node 1     β”‚ β”‚   Node 2     β”‚ β”‚  Node 3    β”‚
  β”‚              β”‚ β”‚              β”‚ β”‚            β”‚
  β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
  β”‚ β”‚LRU Cache β”‚ β”‚ β”‚ β”‚LRU Cache β”‚ β”‚ β”‚ β”‚LRU Cacheβ”‚ β”‚
  β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”˜ β”‚
  β”‚      β”‚       β”‚ β”‚      β”‚       β”‚ β”‚      β”‚     β”‚
  β”‚ β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β” β”‚ β”‚ β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β” β”‚
  β”‚ β”‚   Sled   β”‚ β”‚ β”‚ β”‚   Sled   β”‚ β”‚ β”‚ β”‚  Sled  β”‚ β”‚
  β”‚ β”‚ Database β”‚ β”‚ β”‚ β”‚ Database β”‚ β”‚ β”‚ β”‚Databaseβ”‚ β”‚
  β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”˜ β”‚ β”‚ β””β”€β”€β”€β”€β”¬β”€β”€β”€β”˜ β”‚
  β””β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”˜
         β”‚                β”‚                β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚
          β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
          β”‚    Raft Consensus Layer        β”‚
          β”‚   (Leader Election,            β”‚
          β”‚    Log Replication)            β”‚
          β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚
         β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
         β”‚                β”‚                β”‚
    β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”     β”Œβ”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”
    β”‚S3 Bucketβ”‚      β”‚S3 Bucketβ”‚     β”‚S3 Bucketβ”‚
    β”‚ Node 1  β”‚      β”‚ Node 2  β”‚     β”‚ Node 3  β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜     β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚                β”‚                β”‚
         β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                          β”‚
              β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
              β”‚   MinIO / AWS S3       β”‚
              β”‚  (Cold Storage Tier)   β”‚
              β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Flow

πŸ“ Write Path (Strong Consistency)

  1. Client β†’ Any Node (HTTP PUT)
  2. Forward to Leader (if necessary)
  3. Leader proposes via Raft
  4. Replicate to Quorum
  5. Apply to local storage
  6. Archive to S3 (async)
  7. Success β†’ Client

πŸ“– Read Path (High Performance)

  1. Check LRU Cache β†’ Instant response
  2. Check Sled database β†’ Fast local read
  3. Fetch from S3 β†’ Durable cold storage
  4. Update cache β†’ Optimize future reads

πŸ’» API Reference

πŸ“‘ Core Operations

# Store data
curl -X PUT http://localhost:8001/user:alice \
  -H "Content-Type: text/plain" \
  -d "Alice Johnson"

# Retrieve data
curl http://localhost:8001/user:alice
# Output: Alice Johnson

# Delete data
curl -X DELETE http://localhost:8001/user:alice

πŸ“Š Monitoring Endpoints

# Health check
curl http://localhost:8001/health
# {"status":"ok","node_id":1}

# Raft metrics
curl http://localhost:8001/metrics
# JSON with current_term, current_leader, last_applied...

# Prometheus metrics
curl http://localhost:8001/metrics/prometheus
# Prometheus-formatted metrics

πŸ” Cluster Operations

# Cluster status
curl http://localhost:8001/cluster/info

# List nodes
curl http://localhost:8001/cluster/nodes

# Leader info
curl http://localhost:8001/cluster/leader/info

🌐 Multi-Node Cluster Setup

Option 1: Automated Test Script (Recommended)

# Test 3-node cluster with Docker MinIO S3
./scripts/test-3node-cluster-docker-s3.sh

This script will:

  • βœ… Start MinIO S3 storage in Docker
  • βœ… Create S3 buckets for each node
  • βœ… Start 3 Scribe Ledger nodes
  • βœ… Test data replication
  • βœ… Verify cluster health

Test Report Available: See FINAL_TEST_REPORT.md for detailed results.

Option 2: Manual Cluster Setup

Start Node 1 (Bootstrap):

./target/release/scribe-node --bootstrap --config config-node1.toml

Start Node 2:

./target/release/scribe-node --config config-node2.toml

Start Node 3:

./target/release/scribe-node --config config-node3.toml

Verify cluster:

curl http://localhost:8001/health  # Node 1
curl http://localhost:8002/health  # Node 2
curl http://localhost:8003/health  # Node 3

Option 3: Shell Scripts

./scripts/start-cluster.sh   # Start cluster
./scripts/test-cluster.sh    # Test operations
./scripts/stop-cluster.sh    # Stop cluster

☁️ S3 Storage Configuration

Local Development with MinIO

Start MinIO with Docker:

docker run -d -p 9000:9000 -p 9001:9001 \
  -e MINIO_ROOT_USER=minioadmin \
  -e MINIO_ROOT_PASSWORD=minioadmin \
  --name minio \
  minio/minio server /data --console-address ":9001"

Or use Docker Compose:

docker-compose -f docker-compose-minio.yml up -d

Access MinIO Console: http://localhost:9001 (minioadmin/minioadmin)

Configure Node for S3

Edit config.toml:

[storage.s3]
bucket = "scribe-ledger-node1"
region = "us-east-1"
endpoint = "http://localhost:9000"  # MinIO
access_key_id = "minioadmin"
secret_access_key = "minioadmin"
path_style = true                    # Required for MinIO
pool_size = 10
timeout_secs = 30
max_retries = 3

Data Tiering & Archival

[storage.tiering]
age_threshold_secs = 3600           # Archive after 1 hour
enable_compression = true
compression_level = 6                # 0-9 (balanced)
enable_auto_archival = true
archival_check_interval_secs = 300  # Check every 5 minutes

Features:

  • βœ… Automatic age-based archival
  • βœ… Gzip compression (configurable)
  • βœ… Read-through caching
  • βœ… S3 metadata storage
  • βœ… Lifecycle management

πŸ“š Full Guide: S3 Storage Documentation


πŸ” Cryptographic Verification

Merkle Tree Proofs

Every key-value pair can be cryptographically verified:

# Store data
curl -X PUT http://localhost:8001/test-key \
  -d "verified data"

# Get Merkle proof
curl http://localhost:8001/verify/test-key

Response:

{
  "key": "test-key",
  "verified": true,
  "proof": {
    "root_hash": "a1b2c3d4e5f6...",
    "siblings": ["e5f6g7h8...", "i9j0k1l2..."]
  },
  "error": null
}

Usage in Rust

use hyra_scribe_ledger::crypto::MerkleTree;

// Build tree
let pairs = vec![
    (b"key1".to_vec(), b"value1".to_vec()),
    (b"key2".to_vec(), b"value2".to_vec()),
];
let tree = MerkleTree::from_pairs(pairs);

// Get root hash
let root = tree.root_hash().unwrap();

// Generate & verify proof
let proof = tree.get_proof(b"key1").unwrap();
assert!(MerkleTree::verify_proof(&proof, &root));

⚑ Performance

Benchmarks (Release Build)

Operation Throughput Latency
Local Writes (batched) 200k+ ops/sec < 5ΞΌs
Local Reads (cached) 1.8M+ ops/sec < 1ΞΌs
Mixed Workload 400k+ ops/sec < 10ΞΌs
Distributed Write 10k+ ops/sec < 50ms
Distributed Read (linearizable) 50k+ ops/sec < 10ms
Distributed Read (stale) 200k+ ops/sec < 1ms

Optimizations

  • βœ… LRU Cache Layer - Hot data stays in memory
  • βœ… Async I/O - Tokio runtime for concurrency
  • βœ… Connection Pooling - Reused HTTP/S3 connections
  • βœ… Bincode Serialization - Faster than JSON
  • βœ… Batch Operations - Reduced overhead
  • βœ… Compression - Gzip for S3 transfers

Run benchmarks:

cargo bench

πŸ› οΈ Configuration

Basic Node Configuration

[node]
id = 1
address = "127.0.0.1"
data_dir = "./node-1"

[network]
listen_addr = "127.0.0.1:8001"
client_port = 8001     # HTTP API
raft_port = 9001       # Raft consensus

[storage]
segment_size = 67108864      # 64 MB
max_cache_size = 268435456   # 256 MB

[consensus]
election_timeout_min = 1500  # milliseconds
election_timeout_max = 3000
heartbeat_interval_ms = 300

Environment Variables

Override config with SCRIBE_ prefix:

export SCRIBE_NODE_ID=2
export SCRIBE_NETWORK_CLIENT_PORT=8002
export SCRIBE_NETWORK_RAFT_PORT=9002
cargo run --bin scribe-node

πŸ“š Full Guide: Configuration Documentation


🚒 Deployment

Docker Compose

docker-compose up -d
docker-compose logs -f
docker-compose down

Systemd (Production)

# Install services
sudo cp scripts/systemd/*.service /etc/systemd/system/

# Start cluster
sudo systemctl start scribe-node-{1,2,3}

# Enable on boot
sudo systemctl enable scribe-node-{1,2,3}

# Check status
sudo systemctl status scribe-node-1

πŸ“š Full Guide: Deployment Documentation


πŸ§ͺ Testing

Run All Tests

cargo test

Test Categories

cargo test storage        # Storage layer
cargo test consensus      # Raft consensus
cargo test http_tests     # HTTP API
cargo test cluster        # Multi-node
cargo test crypto         # Merkle proofs

End-to-End Testing

# Python E2E suite
pip install -r tests/e2e/requirements.txt
python3 tests/e2e/cluster_e2e_test.py

# Shell script tests
./scripts/test-cluster.sh

S3 Integration Tests

# Start MinIO first
docker-compose -f docker-compose-minio.yml up -d

# Run S3 tests
cargo test s3_ -- --ignored
cargo test segment_archival -- --ignored
cargo test data_tiering -- --ignored

βœ… Test Report: FINAL_TEST_REPORT.md shows 10/10 passing tests.


πŸ“š Documentation

Document Description
FINAL_TEST_REPORT.md βœ… Complete test results with S3
CLUSTER_TESTING_GUIDE.md πŸ§ͺ How to test multi-node clusters
S3_STORAGE.md ☁️ S3 integration guide
ARCHIVAL_TIERING.md πŸ“¦ Data tiering & archival
CONFIGURATION.md βš™οΈ Configuration reference
DEPLOYMENT.md 🚒 Production deployment
TROUBLESHOOTING.md πŸ”§ Common issues & solutions

🌈 Examples

Basic Usage

cargo run --example basic_usage     # Simple PUT/GET
cargo run --example cli_store       # Interactive CLI
cargo run --example config_demo     # Configuration
cargo run --example data_types      # Type system

Rust Library Usage

use hyra_scribe_ledger::HyraScribeLedger;

fn main() -> anyhow::Result<()> {
    // Create storage
    let ledger = HyraScribeLedger::new("./data")?;
    
    // Store data
    ledger.put("user:alice", "Alice Smith")?;
    
    // Batch operations
    let mut batch = HyraScribeLedger::new_batch();
    batch.insert(b"key1", b"value1");
    batch.insert(b"key2", b"value2");
    ledger.apply_batch(batch)?;
    
    // Retrieve
    if let Some(data) = ledger.get("user:alice")? {
        println!("Found: {}", String::from_utf8_lossy(&data));
    }
    
    // Flush to disk
    ledger.flush()?;
    
    Ok(())
}

🎯 Use Cases

βœ… Perfect For:

  • AI Training Data - Immutable training datasets with verification
  • Blockchain Off-Chain Storage - Scalable storage for blockchain data
  • Audit Trails - Tamper-proof logging with cryptographic proofs
  • Data Archival - Hot/cold tiering for long-term storage
  • Distributed Ledgers - Multi-node consistency with Raft

πŸ’‘ Example Scenarios:

  • AI Model Registry - Store models with versioning and provenance
  • Transaction Logs - Immutable financial transaction records
  • Document Storage - Verified document storage with S3 backing
  • IoT Data - Time-series data with automatic archival
  • Compliance Storage - Regulatory data with audit trails

πŸ”’ Security

Note: Security modules (TLS, authentication, rate limiting) are implemented as library components. Full integration into HTTP server is planned.

  • βœ… Merkle tree verification (active)
  • βœ… SHA-256 cryptographic hashing (active)
  • 🚧 TLS encryption (module ready)
  • 🚧 API key authentication (module ready)
  • 🚧 Role-based access control (module ready)
  • 🚧 Rate limiting (module ready)
  • βœ… Audit logging (active)

πŸ“š Security Guide: Security Documentation


πŸ“Š Monitoring

Prometheus Integration

Scrape configuration:

scrape_configs:
  - job_name: 'hyra-scribe-ledger'
    static_configs:
      - targets: ['localhost:8001', 'localhost:8002', 'localhost:8003']
    metrics_path: '/metrics/prometheus'
    scrape_interval: 15s

Available Metrics:

  • Request latency histograms (p50, p95, p99)
  • Throughput counters (GET/PUT/DELETE)
  • Storage metrics (keys, size)
  • Raft consensus state (term, index, leader)
  • Error counters
  • Cache hit rates

Structured Logging

# Set log level
export RUST_LOG=hyra_scribe_ledger=debug

# Run with tracing
cargo run --bin scribe-node

🀝 Contributing

We welcome contributions! Here's how:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing)
  3. Make your changes
  4. Test thoroughly (cargo test)
  5. Format code (cargo fmt)
  6. Lint code (cargo clippy)
  7. Commit (git commit -am 'Add amazing feature')
  8. Push (git push origin feature/amazing)
  9. Open a Pull Request

Code Quality Standards

  • βœ… No hardcoded values in tests
  • βœ… Comprehensive documentation
  • βœ… Type safety (minimal unwrap())
  • βœ… Consistent formatting (cargo fmt)
  • βœ… Clean code (cargo clippy)

πŸ“„ License

This project is licensed under the MIT License. See LICENSE for details.


πŸŽ‰ Acknowledgments

Built with ❀️ using:


⭐ Star us on GitHub!

Made with πŸ”₯ by the Hyra Team

Documentation β€’ Report Bug β€’ Request Feature

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 4

  •  
  •  
  •  
  •