use std::sync::Arc;
use amaru_kernel::{EraHistory, GlobalParameters, Point};
use amaru_ledger::block_validator::BlockValidator;
use amaru_ouroboros::{CanValidateBlocks, HasStakeDistribution};
use amaru_plutus::arena_pool::ArenaPool;
use amaru_stores::{
in_memory::MemoryStore,
rocksdb::{RocksDB, RocksDBHistoricalStores},
};
use anyhow::anyhow;
use crate::stages::config::{Config, StoreType};
pub enum Ledger {
InMemLedger(BlockValidator<MemoryStore, MemoryStore>),
OnDiskLedger(BlockValidator<RocksDB, RocksDBHistoricalStores>),
}
impl Ledger {
pub fn new(
config: &Config,
era_history: EraHistory,
global_parameters: GlobalParameters,
) -> anyhow::Result<Ledger> {
let vm_eval_pool = ArenaPool::new(config.ledger_vm_alloc_arena_count, config.ledger_vm_alloc_arena_size);
match &config.ledger_store {
StoreType::InMem(store) => {
let ledger = BlockValidator::new(
store.clone(),
store.clone(),
vm_eval_pool,
config.network,
era_history,
global_parameters,
)?;
Ok(Ledger::InMemLedger(ledger))
}
StoreType::RocksDb(rocks_db_config) => {
let ledger = BlockValidator::new(
RocksDB::new(rocks_db_config)?,
RocksDBHistoricalStores::new(rocks_db_config, u64::from(config.max_extra_ledger_snapshots)),
vm_eval_pool,
config.network,
era_history,
global_parameters,
)?;
Ok(Ledger::OnDiskLedger(ledger))
}
}
}
pub fn get_tip(&self) -> Point {
match self {
Ledger::InMemLedger(stage) => stage.get_tip(),
Ledger::OnDiskLedger(stage) => stage.get_tip(),
}
}
pub fn get_stake_distribution(&self) -> anyhow::Result<Arc<dyn HasStakeDistribution>> {
match self {
Ledger::InMemLedger(stage) => {
let state = stage.state.lock().map_err(|e| anyhow!(format!("{e:?}")))?;
Ok(Arc::new(state.view_stake_distribution()))
}
Ledger::OnDiskLedger(stage) => {
let state = stage.state.lock().map_err(|e| anyhow!(format!("{e:?}")))?;
Ok(Arc::new(state.view_stake_distribution()))
}
}
}
pub fn get_block_validation(self) -> Arc<dyn CanValidateBlocks + Send + Sync> {
match self {
Ledger::InMemLedger(stage) => Arc::new(stage),
Ledger::OnDiskLedger(stage) => Arc::new(stage),
}
}
}