Skip to content

Commit 9cc1e74

Browse files
Add backup and benchmark scripts with environment setup
Implement backup and benchmark scripts for RavenChain, enhancing data management and performance testing capabilities. Update .gitignore to include new directories and add environment configuration files for development. Create a setup script to initialize the development environment and generate necessary directories and SSL certificates.
1 parent b405f5c commit 9cc1e74

File tree

6 files changed

+326
-0
lines changed

6 files changed

+326
-0
lines changed

.gitignore

+6
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ wheels/
2020
.installed.cfg
2121
*.egg
2222
.pytest_cache/
23+
backups/
24+
logs/
25+
certs/
26+
data/
2327

2428
# Virtual Environment
2529
venv/
@@ -38,6 +42,8 @@ ENV/
3842
# Local development settings
3943
.env
4044
.env.local
45+
.env.development
46+
.env.production
4147

4248
# System Files
4349
.DS_Store

config/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+

scripts/backup.py

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Backup script for RavenChain data and wallets.
4+
Creates compressed backups with timestamps.
5+
"""
6+
import os
7+
import shutil
8+
import logging
9+
from datetime import datetime
10+
from pathlib import Path
11+
from config.logging import setup_logging
12+
13+
logger = setup_logging("ravenchain.backup")
14+
15+
16+
def create_backup(data_dir: str = "data", backup_dir: str = "backups"):
17+
try:
18+
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
19+
backup_path = Path(backup_dir) / f"ravenchain_backup_{timestamp}"
20+
21+
# Create backup directory if it doesn't exist
22+
Path(backup_dir).mkdir(parents=True, exist_ok=True)
23+
24+
# Create backup
25+
shutil.make_archive(
26+
str(backup_path),
27+
"gztar",
28+
data_dir,
29+
)
30+
31+
logger.info(
32+
"Backup created successfully", backup_file=f"{backup_path}.tar.gz", timestamp=timestamp
33+
)
34+
35+
# Clean old backups (keep last 5)
36+
cleanup_old_backups(backup_dir)
37+
38+
except Exception as e:
39+
logger.error("Backup failed", error=str(e), exc_info=True)
40+
raise
41+
42+
43+
def cleanup_old_backups(backup_dir: str, keep_last: int = 5):
44+
"""Remove old backups, keeping only the specified number of recent ones."""
45+
try:
46+
backups = sorted(Path(backup_dir).glob("ravenchain_backup_*.tar.gz"), key=os.path.getmtime)
47+
48+
# Remove old backups
49+
for backup in backups[:-keep_last]:
50+
backup.unlink()
51+
logger.info("Removed old backup", file=str(backup))
52+
53+
except Exception as e:
54+
logger.error("Cleanup failed", error=str(e), exc_info=True)
55+
56+
57+
if __name__ == "__main__":
58+
create_backup()

scripts/benchmark.py

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Benchmark script for RavenChain performance testing.
4+
Tests transaction processing, mining speed, and chain validation.
5+
"""
6+
import time
7+
import statistics
8+
from typing import List, Tuple, Dict
9+
from config.logging import setup_logging
10+
from ravenchain.blockchain import Blockchain
11+
from ravenchain.wallet import Wallet
12+
13+
logger = setup_logging("ravenchain.benchmark")
14+
15+
16+
class BlockchainBenchmark:
17+
def __init__(self, difficulty: int = 2):
18+
self.blockchain = Blockchain(difficulty=difficulty)
19+
self.wallet = Wallet()
20+
self.wallet_registry: Dict[str, Wallet] = {self.wallet.address: self.wallet}
21+
22+
def benchmark_mining(self, num_blocks: int = 5) -> List[float]:
23+
"""Benchmark mining performance."""
24+
mining_times = []
25+
26+
for _ in range(num_blocks):
27+
# Add some transactions
28+
for _ in range(3):
29+
recipient = Wallet()
30+
self.wallet_registry[recipient.address] = recipient
31+
self.blockchain.add_transaction(
32+
self.wallet.address, recipient.address, 1.0, wallet=self.wallet
33+
)
34+
35+
# Time the mining process
36+
start_time = time.time()
37+
self.blockchain.mine_pending_transactions(self.wallet.address)
38+
mining_times.append(time.time() - start_time)
39+
40+
return mining_times
41+
42+
def benchmark_transaction_processing(self, num_transactions: int = 100) -> float:
43+
"""Benchmark transaction processing speed."""
44+
start_time = time.time()
45+
46+
for _ in range(num_transactions):
47+
recipient = Wallet()
48+
self.wallet_registry[recipient.address] = recipient
49+
self.blockchain.add_transaction(
50+
self.wallet.address, recipient.address, 1.0, wallet=self.wallet
51+
)
52+
53+
return time.time() - start_time
54+
55+
def benchmark_chain_validation(self) -> float:
56+
"""Benchmark chain validation speed."""
57+
# First, create a decent-sized chain
58+
for _ in range(5):
59+
recipient = Wallet()
60+
self.wallet_registry[recipient.address] = recipient
61+
self.blockchain.add_transaction(
62+
self.wallet.address, recipient.address, 1.0, wallet=self.wallet
63+
)
64+
self.blockchain.mine_pending_transactions(self.wallet.address)
65+
66+
# Time the validation
67+
start_time = time.time()
68+
self.blockchain.is_chain_valid(self.wallet_registry)
69+
return time.time() - start_time
70+
71+
72+
def run_benchmarks() -> Tuple[List[float], float, float]:
73+
"""Run all benchmarks and return results."""
74+
try:
75+
benchmark = BlockchainBenchmark()
76+
77+
# Mining benchmark
78+
logger.info("Starting mining benchmark")
79+
mining_times = benchmark.benchmark_mining()
80+
avg_mining_time = statistics.mean(mining_times)
81+
logger.info(
82+
"Mining benchmark complete", avg_time=f"{avg_mining_time:.2f}s", times=mining_times
83+
)
84+
85+
# Transaction processing benchmark
86+
logger.info("Starting transaction processing benchmark")
87+
tx_time = benchmark.benchmark_transaction_processing()
88+
logger.info(
89+
"Transaction benchmark complete",
90+
total_time=f"{tx_time:.2f}s",
91+
transactions_per_second=f"{100/tx_time:.2f}",
92+
)
93+
94+
# Chain validation benchmark
95+
logger.info("Starting chain validation benchmark")
96+
validation_time = benchmark.benchmark_chain_validation()
97+
logger.info("Validation benchmark complete", validation_time=f"{validation_time:.2f}s")
98+
99+
return mining_times, tx_time, validation_time
100+
101+
except Exception as e:
102+
logger.error("Benchmark failed", error=str(e), exc_info=True)
103+
raise
104+
105+
106+
if __name__ == "__main__":
107+
run_benchmarks()

scripts/generate_test_data.py

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Generate test data for RavenChain development and testing.
4+
Creates wallets, transactions, and mines blocks.
5+
"""
6+
import random
7+
from pathlib import Path
8+
from config.logging import setup_logging
9+
from ravenchain.blockchain import Blockchain
10+
from ravenchain.wallet import Wallet
11+
12+
logger = setup_logging("ravenchain.testdata")
13+
14+
15+
def generate_test_data(
16+
num_wallets: int = 5,
17+
num_transactions: int = 20,
18+
min_amount: float = 0.1,
19+
max_amount: float = 10.0,
20+
):
21+
try:
22+
# Initialize blockchain
23+
blockchain = Blockchain(difficulty=2)
24+
wallets = []
25+
26+
# Create wallets
27+
logger.info("Creating test wallets", count=num_wallets)
28+
for i in range(num_wallets):
29+
wallet = Wallet()
30+
wallets.append(wallet)
31+
logger.debug(f"Created wallet {i+1}", address=wallet.address)
32+
33+
# Generate transactions
34+
logger.info("Generating test transactions", count=num_transactions)
35+
for _ in range(num_transactions):
36+
sender = random.choice(wallets)
37+
receiver = random.choice([w for w in wallets if w != sender])
38+
amount = random.uniform(min_amount, max_amount)
39+
40+
blockchain.add_transaction(sender.address, receiver.address, amount, wallet=sender)
41+
42+
# Mine a block after every few transactions
43+
if random.random() < 0.3: # 30% chance to mine
44+
miner = random.choice(wallets)
45+
blockchain.mine_pending_transactions(miner.address)
46+
logger.info("Mined a new block", miner=miner.address)
47+
48+
# Mine any remaining transactions
49+
if blockchain.pending_transactions:
50+
miner = random.choice(wallets)
51+
blockchain.mine_pending_transactions(miner.address)
52+
logger.info("Mined final block", miner=miner.address)
53+
54+
# Log final state
55+
logger.info(
56+
"Test data generation complete",
57+
total_blocks=len(blockchain.chain),
58+
total_wallets=len(wallets),
59+
total_transactions=num_transactions,
60+
)
61+
62+
return blockchain, wallets
63+
64+
except Exception as e:
65+
logger.error("Test data generation failed", error=str(e), exc_info=True)
66+
raise
67+
68+
69+
if __name__ == "__main__":
70+
generate_test_data()

scripts/setup_dev.py

+84
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Development environment setup script for RavenChain.
4+
Creates necessary directories, generates test certificates, and sets up initial configuration.
5+
"""
6+
import os
7+
import sys
8+
from pathlib import Path
9+
from config.logging import setup_logging
10+
11+
logger = setup_logging("ravenchain.setup")
12+
13+
14+
def setup_development_environment():
15+
"""Set up the development environment."""
16+
try:
17+
# Create necessary directories
18+
directories = ["data", "logs", "backups", "certs", "config"]
19+
20+
for directory in directories:
21+
Path(directory).mkdir(parents=True, exist_ok=True)
22+
logger.info(f"Created directory: {directory}")
23+
24+
# Create development environment file if it doesn't exist
25+
env_file = Path(".env.development")
26+
if not env_file.exists():
27+
env_content = """# Development Environment Configuration
28+
ENVIRONMENT=development
29+
DEBUG=1
30+
RAVENCHAIN_DATA_DIR=data
31+
RAVENCHAIN_LOGS_DIR=logs
32+
MINING_DIFFICULTY=2
33+
LOG_LEVEL=DEBUG
34+
LOG_JSON=1
35+
36+
# Database Configuration (for future use)
37+
# DB_HOST=localhost
38+
# DB_PORT=5432
39+
# DB_NAME=ravenchain
40+
# DB_USER=ravenchain
41+
# DB_PASSWORD=ravenchain
42+
43+
# API Configuration (for future use)
44+
# API_HOST=0.0.0.0
45+
# API_PORT=8000
46+
# API_WORKERS=4
47+
# CORS_ORIGINS=http://localhost:3000
48+
"""
49+
env_file.write_text(env_content)
50+
logger.info("Created development environment file")
51+
52+
# Create test SSL certificates for development
53+
if not Path("certs/dev.key").exists():
54+
os.system(
55+
"openssl req -x509 -newkey rsa:4096 -keyout certs/dev.key "
56+
"-out certs/dev.crt -days 365 -nodes -subj '/CN=localhost'"
57+
)
58+
logger.info("Generated development SSL certificates")
59+
60+
# Initialize git hooks if in a git repository
61+
git_dir = Path(".git")
62+
if git_dir.exists():
63+
hooks_dir = git_dir / "hooks"
64+
65+
# Create pre-commit hook
66+
pre_commit = hooks_dir / "pre-commit"
67+
pre_commit_content = """#!/bin/sh
68+
# Activate virtual environment and run tests
69+
. "./venv/Scripts/activate"
70+
python -m pytest tests/
71+
"""
72+
pre_commit.write_text(pre_commit_content)
73+
pre_commit.chmod(0o755)
74+
logger.info("Set up git pre-commit hook")
75+
76+
logger.info("Development environment setup complete")
77+
78+
except Exception as e:
79+
logger.error("Setup failed", error=str(e), exc_info=True)
80+
sys.exit(1)
81+
82+
83+
if __name__ == "__main__":
84+
setup_development_environment()

0 commit comments

Comments
 (0)