use crate::{
blockchain::{config::GenesisConfig, Blockchain, BlockchainMut, Schema},
runtime::{Dispatcher, RuntimeInstance},
};
#[derive(Debug)]
pub struct BlockchainBuilder {
blockchain: Blockchain,
runtimes: Vec<RuntimeInstance>,
genesis_config: Option<GenesisConfig>,
}
impl BlockchainBuilder {
pub fn new(blockchain: Blockchain) -> Self {
Self {
blockchain,
runtimes: vec![],
genesis_config: None,
}
}
pub fn with_genesis_config(mut self, genesis_config: GenesisConfig) -> Self {
self.genesis_config = Some(genesis_config);
self
}
pub fn with_runtime(mut self, runtime: impl Into<RuntimeInstance>) -> Self {
self.runtimes.push(runtime.into());
self
}
pub fn build(self) -> BlockchainMut {
const NO_GENESIS_CFG: &str =
"No genesis config was provided for an uninitialized blockchain";
let mut blockchain = BlockchainMut {
dispatcher: Dispatcher::new(&self.blockchain, self.runtimes),
inner: self.blockchain,
};
let snapshot = blockchain.snapshot();
let has_genesis_block = !Schema::new(&snapshot).block_hashes_by_height().is_empty();
if has_genesis_block {
blockchain.dispatcher.restore_state(&snapshot);
} else {
let genesis_config = self.genesis_config.expect(NO_GENESIS_CFG);
blockchain.create_genesis_block(genesis_config);
};
blockchain
}
}