cuprate-hinto-janai/consensus/src/verifier.rs
2023-10-15 20:35:33 +01:00

125 lines
3.4 KiB
Rust

use futures::join;
use monero_serai::{block::Block, transaction::Transaction};
use tower::ServiceExt;
use tracing::instrument;
use crate::{
block::{
difficulty::{DifficultyCache, DifficultyCacheConfig},
weight::{BlockWeightsCache, BlockWeightsCacheConfig},
},
hardforks::{HardForkConfig, HardForkState},
ConsensusError, Database, DatabaseRequest, DatabaseResponse,
};
pub struct Config {
hard_fork_cfg: HardForkConfig,
difficulty_cfg: DifficultyCacheConfig,
weights_config: BlockWeightsCacheConfig,
}
impl Config {
pub fn main_net() -> Config {
Config {
hard_fork_cfg: HardForkConfig::main_net(),
difficulty_cfg: DifficultyCacheConfig::main_net(),
weights_config: BlockWeightsCacheConfig::main_net(),
}
}
}
#[derive(Clone)]
struct State {
block_weight: BlockWeightsCache,
difficulty: DifficultyCache,
hard_fork: HardForkState,
chain_height: u64,
top_hash: [u8; 32],
}
impl State {
pub async fn init<D: Database + Clone>(
config: Config,
mut database: D,
) -> Result<State, ConsensusError> {
let DatabaseResponse::ChainHeight(chain_height) = database
.ready()
.await?
.call(DatabaseRequest::ChainHeight)
.await?
else {
panic!("Database sent incorrect response")
};
Self::init_at_chain_height(config, chain_height, database).await
}
pub async fn init_at_chain_height<D: Database + Clone>(
config: Config,
chain_height: u64,
mut database: D,
) -> Result<State, ConsensusError> {
let DatabaseResponse::BlockHash(top_hash) = database
.ready()
.await?
.call(DatabaseRequest::BlockHash(chain_height - 1))
.await?
else {
panic!("Database sent incorrect response")
};
let (block_weight, difficulty, hard_fork) = join!(
BlockWeightsCache::init_from_chain_height(
chain_height,
config.weights_config,
database.clone()
),
DifficultyCache::init_from_chain_height(
chain_height,
config.difficulty_cfg,
database.clone()
),
HardForkState::init_from_chain_height(config.hard_fork_cfg, chain_height, database)
);
Ok(State {
block_weight: block_weight?,
difficulty: difficulty?,
hard_fork: hard_fork?,
chain_height,
top_hash,
})
}
}
pub struct Verifier {
state: State,
}
impl Verifier {
pub async fn init<D: Database + Clone>(
config: Config,
mut database: D,
) -> Result<Verifier, ConsensusError> {
let DatabaseResponse::ChainHeight(chain_height) = database
.ready()
.await?
.call(DatabaseRequest::ChainHeight)
.await?
else {
panic!("Database sent incorrect response")
};
Self::init_at_chain_height(config, chain_height, database).await
}
pub async fn init_at_chain_height<D: Database + Clone>(
config: Config,
chain_height: u64,
database: D,
) -> Result<Verifier, ConsensusError> {
Ok(Verifier {
state: State::init_at_chain_height(config, chain_height, database).await?,
})
}
}