#[cfg(feature = "rocksdb")]
mod bitcoin_core_tests {
use blvm_node::storage::bitcoin_core_blocks::BitcoinCoreBlockReader;
use blvm_node::storage::bitcoin_core_detection::{BitcoinCoreDetection, BitcoinCoreNetwork};
use blvm_node::storage::bitcoin_core_format::{
convert_key, get_key_prefix, parse_block_index, parse_coin,
};
use std::fs::{create_dir_all, File};
use std::io::Write;
use tempfile::TempDir;
#[test]
fn test_bitcoin_core_detection_paths() {
let result = BitcoinCoreDetection::detect_data_dir(BitcoinCoreNetwork::Mainnet);
assert!(result.is_ok());
}
#[test]
fn test_bitcoin_core_network_detection() {
let temp_dir = TempDir::new().unwrap();
let mainnet_path = temp_dir.path().join(".bitcoin");
create_dir_all(&mainnet_path).unwrap();
let detected = BitcoinCoreDetection::detect_network(&mainnet_path);
assert_eq!(detected, Some(BitcoinCoreNetwork::Mainnet));
let testnet_path = temp_dir.path().join("testnet3");
create_dir_all(&testnet_path).unwrap();
let detected = BitcoinCoreDetection::detect_network(&testnet_path);
assert_eq!(detected, Some(BitcoinCoreNetwork::Testnet));
}
#[test]
fn test_key_conversion() {
let coin_key = b"c\x01\x02\x03";
let converted = convert_key(coin_key).unwrap();
assert_eq!(converted, b"\x01\x02\x03");
let block_key = b"b\x04\x05\x06";
let converted = convert_key(block_key).unwrap();
assert_eq!(converted, b"\x04\x05\x06");
}
#[test]
fn test_get_key_prefix() {
let coin_key = b"c\x01\x02\x03";
assert_eq!(get_key_prefix(coin_key), Some(b'c'));
let block_key = b"b\x04\x05\x06";
assert_eq!(get_key_prefix(block_key), Some(b'b'));
let empty_key = b"";
assert_eq!(get_key_prefix(empty_key), None);
}
#[test]
fn test_parse_coin_simple() {
let mut data = Vec::new();
data.push(0x00);
data.push(0x06);
data.extend_from_slice(b"script");
data.extend_from_slice(&1000000u64.to_le_bytes());
data.extend_from_slice(&100u32.to_le_bytes());
data.push(0x01);
let coin = parse_coin(&data).unwrap();
assert_eq!(coin.amount, 1000000);
assert_eq!(coin.height, 100);
assert_eq!(coin.is_coinbase, true);
assert_eq!(coin.script, b"script");
}
#[test]
fn test_parse_block_index() {
let mut data = vec![0u8; 104];
data[0..4].copy_from_slice(&100u32.to_le_bytes());
data[4..8].copy_from_slice(&1u32.to_le_bytes());
data[8..12].copy_from_slice(&10u32.to_le_bytes());
data[12..16].copy_from_slice(&0u32.to_le_bytes());
data[16..20].copy_from_slice(&0u32.to_le_bytes());
data[20..24].copy_from_slice(&0u32.to_le_bytes());
data[24..28].copy_from_slice(&1u32.to_le_bytes());
data[28..60].copy_from_slice(&[0u8; 32]);
data[60..92].copy_from_slice(&[1u8; 32]);
data[92..96].copy_from_slice(&1234567890u32.to_le_bytes());
data[96..100].copy_from_slice(&0x1d00ffffu32.to_le_bytes());
data[100..104].copy_from_slice(&12345u32.to_le_bytes());
let block_index = parse_block_index(&data).unwrap();
assert_eq!(block_index.height, 100);
assert_eq!(block_index.n_tx, 10);
assert_eq!(block_index.n_time, 1234567890);
assert_eq!(block_index.n_bits, 0x1d00ffff);
assert_eq!(block_index.n_nonce, 12345);
}
#[test]
fn test_block_file_reader_with_cache() {
let temp_dir = TempDir::new().unwrap();
let blocks_dir = temp_dir.path().join("blocks");
create_dir_all(&blocks_dir).unwrap();
let file_path = blocks_dir.join("blk00000.dat");
let mut file = File::create(&file_path).unwrap();
file.write_all(&[0xF9, 0xBE, 0xB4, 0xD9]).unwrap();
file.write_all(&80u32.to_le_bytes()).unwrap();
file.write_all(&vec![0u8; 80]).unwrap();
let cache_dir = temp_dir.path().join("cache");
let reader = BitcoinCoreBlockReader::new_with_cache(
&blocks_dir,
BitcoinCoreNetwork::Mainnet,
Some(&cache_dir),
);
assert!(reader.is_ok());
let reader = reader.unwrap();
let count = reader.block_count().unwrap();
assert!(count > 0);
let count2 = reader.block_count().unwrap();
assert_eq!(count, count2);
let cache_file = cache_dir.join("block_index_mainnet.bin");
assert!(cache_file.exists());
}
#[test]
fn test_block_file_reader_index_persistence() {
let temp_dir = TempDir::new().unwrap();
let blocks_dir = temp_dir.path().join("blocks");
create_dir_all(&blocks_dir).unwrap();
let file_path = blocks_dir.join("blk00000.dat");
let mut file = File::create(&file_path).unwrap();
file.write_all(&[0xF9, 0xBE, 0xB4, 0xD9]).unwrap();
file.write_all(&80u32.to_le_bytes()).unwrap();
file.write_all(&vec![0u8; 80]).unwrap();
let cache_dir = temp_dir.path().join("cache");
let reader1 = BitcoinCoreBlockReader::new_with_cache(
&blocks_dir,
BitcoinCoreNetwork::Mainnet,
Some(&cache_dir),
)
.unwrap();
let count1 = reader1.block_count().unwrap();
let reader2 = BitcoinCoreBlockReader::new_with_cache(
&blocks_dir,
BitcoinCoreNetwork::Mainnet,
Some(&cache_dir),
)
.unwrap();
let count2 = reader2.block_count().unwrap();
assert_eq!(count1, count2);
}
}
#[cfg(not(feature = "rocksdb"))]
mod bitcoin_core_tests {
#[test]
fn test_bitcoin_core_not_available() {
use blvm_node::storage::bitcoin_core_detection::BitcoinCoreNetwork;
use blvm_node::storage::bitcoin_core_storage::BitcoinCoreStorage;
use tempfile::TempDir;
let temp_dir = TempDir::new().unwrap();
let result = BitcoinCoreStorage::open_bitcoin_core_database(
temp_dir.path(),
BitcoinCoreNetwork::Mainnet,
);
assert!(result.is_err());
}
}