1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
//! Bitcoin Core storage integration
//!
//! Integrates Bitcoin Core detection and format parsing with the storage layer.
use crate::storage::bitcoin_core_detection::{BitcoinCoreDetection, BitcoinCoreNetwork};
use crate::storage::database::{create_database, DatabaseBackend};
use anyhow::Result;
use std::path::Path;
/// Storage initialization with Bitcoin Core detection
pub struct BitcoinCoreStorage;
impl BitcoinCoreStorage {
/// Detect and initialize storage from Bitcoin Core data
///
/// This function:
/// 1. Detects if Bitcoin Core data exists
/// 2. If found, opens it with RocksDB (which can read LevelDB format)
/// 3. Returns the appropriate database backend
#[cfg(feature = "rocksdb")]
pub fn detect_and_open(
data_dir: &Path,
network: BitcoinCoreNetwork,
) -> Result<Option<DatabaseBackend>> {
// Check for existing BLVM database first
if Self::has_blvm_database(data_dir) {
// Use existing BLVM database (don't try Bitcoin Core)
return Ok(None);
}
// Try to detect Bitcoin Core data
if let Some(core_dir) = BitcoinCoreDetection::detect_data_dir(network)? {
// Verify database format
let chainstate = core_dir.join("chainstate");
if BitcoinCoreDetection::detect_db_format(&chainstate).is_ok() {
// Bitcoin Core LevelDB database found
// Return RocksDB backend (can read LevelDB format)
return Ok(Some(DatabaseBackend::RocksDB));
}
}
Ok(None)
}
#[cfg(not(feature = "rocksdb"))]
pub fn detect_and_open(
_data_dir: &Path,
_network: BitcoinCoreNetwork,
) -> Result<Option<DatabaseBackend>> {
// RocksDB not available, cannot detect Bitcoin Core
Ok(None)
}
/// Check if BLVM database already exists
fn has_blvm_database(data_dir: &Path) -> bool {
// Check for redb database
let redb_path = data_dir.join("redb.db");
if redb_path.exists() {
return true;
}
// Check for sled database
let sled_path = data_dir.join("sled");
if sled_path.exists() {
return true;
}
// Check for rocksdb database (BLVM format, not Bitcoin Core)
let rocksdb_path = data_dir.join("rocksdb");
if rocksdb_path.exists() {
return true;
}
false
}
/// Open Bitcoin Core database with RocksDB
///
/// Opens the Bitcoin Core chainstate database using RocksDB's LevelDB compatibility.
#[cfg(feature = "rocksdb")]
pub fn open_bitcoin_core_database(
data_dir: &Path,
network: BitcoinCoreNetwork,
) -> Result<Box<dyn crate::storage::database::Database>> {
use crate::storage::database::rocksdb_impl::RocksDBDatabase;
if let Some(core_dir) = BitcoinCoreDetection::detect_data_dir(network)? {
// Verify database integrity
BitcoinCoreDetection::verify_database(&core_dir)?;
// Open with RocksDB (can read LevelDB format)
let db = RocksDBDatabase::open_bitcoin_core(&core_dir)?;
Ok(Box::new(db))
} else {
Err(anyhow::anyhow!("Bitcoin Core data directory not found"))
}
}
/// When RocksDB is disabled, opening Core chainstate is unsupported (API still exists for tests).
#[cfg(not(feature = "rocksdb"))]
pub fn open_bitcoin_core_database(
_data_dir: &Path,
_network: BitcoinCoreNetwork,
) -> Result<Box<dyn crate::storage::database::Database>> {
Err(anyhow::anyhow!("RocksDB feature not enabled"))
}
}